@trezor/connect 9.2.3 → 9.2.4-beta.1
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 +43 -5
- package/README.md +1 -1
- package/lib/api/applyFlags.d.ts +8 -1
- package/lib/api/applyFlags.js +3 -8
- package/lib/api/applySettings.d.ts +8 -1
- package/lib/api/applySettings.js +3 -8
- package/lib/api/backupDevice.d.ts +10 -2
- package/lib/api/backupDevice.js +12 -9
- package/lib/api/binance/api/binanceGetAddress.d.ts +4 -3
- package/lib/api/binance/api/binanceGetAddress.js +8 -22
- package/lib/api/binance/api/binanceGetPublicKey.d.ts +4 -2
- package/lib/api/binance/api/binanceGetPublicKey.js +6 -18
- package/lib/api/cardano/api/cardanoGetAddress.d.ts +4 -3
- package/lib/api/cardano/api/cardanoGetAddress.js +8 -22
- package/lib/api/cardano/api/cardanoGetPublicKey.d.ts +4 -3
- package/lib/api/cardano/api/cardanoGetPublicKey.js +9 -31
- package/lib/api/changeLanguage.d.ts +8 -1
- package/lib/api/changeLanguage.js +3 -7
- package/lib/api/eos/api/eosGetPublicKey.d.ts +4 -2
- package/lib/api/eos/api/eosGetPublicKey.js +6 -18
- package/lib/api/ethereum/api/ethereumGetAddress.d.ts +4 -3
- package/lib/api/ethereum/api/ethereumGetAddress.js +4 -20
- package/lib/api/ethereum/api/ethereumGetPublicKey.d.ts +4 -2
- package/lib/api/ethereum/api/ethereumGetPublicKey.js +3 -10
- package/lib/api/firmware/index.d.ts +2 -0
- package/lib/api/firmware/index.js +5 -1
- package/lib/api/firmware/parseFirmwareHeaders.d.ts +5 -0
- package/lib/api/firmware/parseFirmwareHeaders.js +35 -0
- package/lib/api/firmware/uploadFirmware.d.ts +1 -1
- package/lib/api/firmware/uploadFirmware.js +9 -1
- package/lib/api/getAccountDescriptor.d.ts +5 -3
- package/lib/api/getAccountDescriptor.js +8 -21
- package/lib/api/getAccountInfo.d.ts +23 -7
- package/lib/api/getAccountInfo.js +12 -25
- package/lib/api/getAddress.d.ts +4 -3
- package/lib/api/getAddress.js +8 -22
- package/lib/api/getFeatures.d.ts +1 -0
- package/lib/api/getOwnershipId.d.ts +4 -2
- package/lib/api/getOwnershipId.js +4 -15
- package/lib/api/getOwnershipProof.d.ts +4 -2
- package/lib/api/getOwnershipProof.js +4 -15
- package/lib/api/getPublicKey.d.ts +5 -4
- package/lib/api/getPublicKey.js +12 -35
- package/lib/api/index.d.ts +0 -1
- package/lib/api/index.js +1 -3
- package/lib/api/nem/api/nemGetAddress.d.ts +4 -3
- package/lib/api/nem/api/nemGetAddress.js +4 -20
- package/lib/api/rebootToBootloader.d.ts +8 -2
- package/lib/api/rebootToBootloader.js +3 -10
- package/lib/api/recoveryDevice.d.ts +8 -1
- package/lib/api/recoveryDevice.js +3 -7
- package/lib/api/resetDevice.d.ts +4 -2
- package/lib/api/resetDevice.js +3 -10
- package/lib/api/ripple/api/rippleGetAddress.d.ts +4 -3
- package/lib/api/ripple/api/rippleGetAddress.js +4 -20
- package/lib/api/solana/api/solanaGetAddress.d.ts +4 -3
- package/lib/api/solana/api/solanaGetAddress.js +7 -28
- package/lib/api/solana/api/solanaGetPublicKey.d.ts +4 -3
- package/lib/api/solana/api/solanaGetPublicKey.js +7 -27
- package/lib/api/stellar/api/stellarGetAddress.d.ts +4 -3
- package/lib/api/stellar/api/stellarGetAddress.js +4 -20
- package/lib/api/tezos/api/tezosGetAddress.d.ts +4 -3
- package/lib/api/tezos/api/tezosGetAddress.js +4 -20
- package/lib/api/tezos/api/tezosGetPublicKey.d.ts +4 -2
- package/lib/api/tezos/api/tezosGetPublicKey.js +6 -18
- package/lib/api/wipeDevice.d.ts +8 -2
- package/lib/api/wipeDevice.js +3 -10
- package/lib/constants/errors.d.ts +1 -0
- package/lib/constants/errors.js +1 -0
- package/lib/core/AbstractMethod.d.ts +4 -8
- package/lib/core/AbstractMethod.js +6 -28
- package/lib/core/index.d.ts +2 -1
- package/lib/core/index.js +254 -225
- package/lib/core/onCallFirmwareUpdate.d.ts +31 -0
- package/lib/core/onCallFirmwareUpdate.js +259 -0
- package/lib/data/analyticsInfo.d.ts +2 -2
- package/lib/data/analyticsInfo.js +6 -7
- package/lib/data/deviceAuthenticityConfig.js +8 -4
- package/lib/data/firmwareInfo.js +1 -1
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +1 -1
- package/lib/device/Device.js +2 -2
- package/lib/device/DeviceCommands.d.ts +2 -14
- package/lib/device/DeviceCommands.js +1 -43
- package/lib/device/DeviceList.d.ts +1 -1
- package/lib/device/DeviceList.js +20 -15
- package/lib/events/index.d.ts +1 -0
- package/lib/events/ui-request.d.ts +13 -1
- package/lib/events/ui-request.js +1 -0
- package/lib/index.js +2 -2
- package/lib/types/api/backupDevice.d.ts +2 -2
- package/lib/types/api/dispose.d.ts +1 -1
- package/lib/types/api/firmwareUpdate.d.ts +7 -6
- package/lib/types/api/firmwareUpdate.js +1 -3
- package/lib/utils/popupPromiseManager.d.ts +8 -0
- package/lib/utils/popupPromiseManager.js +21 -0
- package/lib/utils/uiPromiseManager.d.ts +38 -0
- package/lib/utils/uiPromiseManager.js +47 -0
- package/lib/workers/workers-browser.d.ts +3 -1
- package/lib/workers/workers-browser.js +2 -2
- package/package.json +6 -6
- package/lib/api/firmwareUpdate.d.ts +0 -19
- package/lib/api/firmwareUpdate.js +0 -78
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DeviceList } from '../device/DeviceList';
|
|
2
|
+
import { CoreEventMessage } from '../events';
|
|
3
|
+
import { CommonParams } from '../types';
|
|
4
|
+
import type { Log } from '../utils/debug';
|
|
5
|
+
import type { Device } from '../device/Device';
|
|
6
|
+
type PostMessage = (message: CoreEventMessage) => void;
|
|
7
|
+
export type Params = {
|
|
8
|
+
language?: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
btcOnly?: boolean;
|
|
11
|
+
binary?: ArrayBuffer;
|
|
12
|
+
} & CommonParams;
|
|
13
|
+
type Context = {
|
|
14
|
+
deviceList: DeviceList;
|
|
15
|
+
postMessage: PostMessage;
|
|
16
|
+
initDevice: (path?: string) => Promise<Device>;
|
|
17
|
+
log: Log;
|
|
18
|
+
abortSignal: AbortSignal;
|
|
19
|
+
};
|
|
20
|
+
export declare const onCallFirmwareUpdate: ({ params, context: { deviceList, postMessage, initDevice, log, abortSignal }, }: {
|
|
21
|
+
params: Params;
|
|
22
|
+
context: Context;
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
check: "other-error";
|
|
25
|
+
checkError: any;
|
|
26
|
+
} | {
|
|
27
|
+
check: string;
|
|
28
|
+
checkError?: undefined;
|
|
29
|
+
}>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=onCallFirmwareUpdate.d.ts.map
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onCallFirmwareUpdate = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const utils_1 = require("@trezor/utils");
|
|
6
|
+
const events_1 = require("../events");
|
|
7
|
+
const firmware_1 = require("../api/firmware");
|
|
8
|
+
const firmwareInfo_1 = require("../data/firmwareInfo");
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
const versionUtils_1 = require("@trezor/utils/lib/versionUtils");
|
|
11
|
+
const registerEvents = (device, postMessage) => {
|
|
12
|
+
device.on(events_1.DEVICE.BUTTON, (_d, request) => {
|
|
13
|
+
postMessage((0, events_1.createDeviceMessage)(events_1.DEVICE.BUTTON, {
|
|
14
|
+
code: request.code,
|
|
15
|
+
device: device.toMessageObject(),
|
|
16
|
+
}));
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
const waitForReconnectedDevice = async ({ bootloader, method, intermediary }, { deviceList, device, postMessage, log, abortSignal }) => {
|
|
20
|
+
const target = intermediary || !bootloader ? 'normal' : 'bootloader';
|
|
21
|
+
let i = 0;
|
|
22
|
+
if (method !== 'auto') {
|
|
23
|
+
log.debug('onCallFirmwareUpdate', 'waiting for device to disconnect');
|
|
24
|
+
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_RECONNECT, {
|
|
25
|
+
device: device.toMessageObject(),
|
|
26
|
+
disconnected: false,
|
|
27
|
+
method,
|
|
28
|
+
target,
|
|
29
|
+
i,
|
|
30
|
+
}));
|
|
31
|
+
await new Promise(resolve => {
|
|
32
|
+
deviceList.once('device-disconnect', resolve);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
log.debug('onCallFirmwareUpdate', `waiting for device to reconnect in ${bootloader ? 'bootloader' : 'normal'} mode`);
|
|
36
|
+
let reconnectedDevice;
|
|
37
|
+
do {
|
|
38
|
+
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_RECONNECT, {
|
|
39
|
+
device: device.toMessageObject(),
|
|
40
|
+
disconnected: true,
|
|
41
|
+
method,
|
|
42
|
+
target,
|
|
43
|
+
i,
|
|
44
|
+
}));
|
|
45
|
+
await (0, utils_1.createTimeoutPromise)(2000);
|
|
46
|
+
try {
|
|
47
|
+
const path = deviceList.getFirstDevicePath();
|
|
48
|
+
reconnectedDevice = deviceList.getDevice(path);
|
|
49
|
+
}
|
|
50
|
+
catch { }
|
|
51
|
+
i++;
|
|
52
|
+
log.debug('onCallFirmwareUpdate', 'waiting for device to reconnect', i);
|
|
53
|
+
} while (!abortSignal.aborted &&
|
|
54
|
+
(!(reconnectedDevice === null || reconnectedDevice === void 0 ? void 0 : reconnectedDevice.features) ||
|
|
55
|
+
bootloader === !reconnectedDevice.features.bootloader_mode ||
|
|
56
|
+
(intermediary &&
|
|
57
|
+
!(0, versionUtils_1.isNewer)([
|
|
58
|
+
reconnectedDevice.features.major_version,
|
|
59
|
+
reconnectedDevice.features.minor_version,
|
|
60
|
+
reconnectedDevice.features.patch_version,
|
|
61
|
+
], [
|
|
62
|
+
device.features.major_version,
|
|
63
|
+
device.features.minor_version,
|
|
64
|
+
device.features.patch_version,
|
|
65
|
+
]))));
|
|
66
|
+
if (!reconnectedDevice) {
|
|
67
|
+
throw constants_1.ERRORS.TypedError('Method_Interrupted');
|
|
68
|
+
}
|
|
69
|
+
registerEvents(reconnectedDevice, postMessage);
|
|
70
|
+
await reconnectedDevice.waitForFirstRun();
|
|
71
|
+
await reconnectedDevice.acquire();
|
|
72
|
+
return reconnectedDevice;
|
|
73
|
+
};
|
|
74
|
+
const getInstallationParams = (device, binary) => {
|
|
75
|
+
var _a;
|
|
76
|
+
if (!device.features.bootloader_mode) {
|
|
77
|
+
const version = binary ? (0, firmware_1.parseFirmwareHeaders)(Buffer.from(binary)).version : undefined;
|
|
78
|
+
const isUpdatingToNewerVersion = !version
|
|
79
|
+
? (_a = device.firmwareRelease) === null || _a === void 0 ? void 0 : _a.isNewer
|
|
80
|
+
: (0, versionUtils_1.isNewer)(version, [
|
|
81
|
+
device.features.major_version,
|
|
82
|
+
device.features.minor_version,
|
|
83
|
+
device.features.patch_version,
|
|
84
|
+
]);
|
|
85
|
+
const upgrade = device.atLeast('2.6.3') && isUpdatingToNewerVersion;
|
|
86
|
+
const manual = !device.atLeast(['1.10.0', '2.6.0']) && !upgrade;
|
|
87
|
+
const language = device.atLeast('2.7.0');
|
|
88
|
+
return {
|
|
89
|
+
manual,
|
|
90
|
+
upgrade,
|
|
91
|
+
language,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return {
|
|
96
|
+
manual: false,
|
|
97
|
+
upgrade: false,
|
|
98
|
+
language: false,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const getFwHeader = (binary) => Buffer.from(binary.slice(0, 6000)).toString('hex');
|
|
103
|
+
const getBinaryHelper = (device, params, log, postMessage, intermediaryVersion) => {
|
|
104
|
+
var _a;
|
|
105
|
+
if (!device.firmwareRelease) {
|
|
106
|
+
throw constants_1.ERRORS.TypedError('Runtime', 'device.firmwareRelease is not set');
|
|
107
|
+
}
|
|
108
|
+
const btcOnly = params.btcOnly || (params.btcOnly === undefined && device.firmwareType === 'bitcoin-only');
|
|
109
|
+
log.debug('onCallFirmwareUpdate loading binary', 'intermediaryVersion', intermediaryVersion, 'version', device.firmwareRelease.release.version, 'btcOnly', btcOnly);
|
|
110
|
+
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
|
|
111
|
+
device: device.toMessageObject(),
|
|
112
|
+
operation: 'downloading',
|
|
113
|
+
progress: 0,
|
|
114
|
+
}));
|
|
115
|
+
return (0, firmware_1.getBinary)({
|
|
116
|
+
features: device.features,
|
|
117
|
+
releases: (0, firmwareInfo_1.getReleases)((_a = device.features) === null || _a === void 0 ? void 0 : _a.internal_model),
|
|
118
|
+
baseUrl: params.baseUrl || 'https://data.trezor.io',
|
|
119
|
+
version: device.firmwareRelease.release.version,
|
|
120
|
+
btcOnly,
|
|
121
|
+
intermediaryVersion,
|
|
122
|
+
}).then(res => {
|
|
123
|
+
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
|
|
124
|
+
device: device.toMessageObject(),
|
|
125
|
+
operation: 'downloading',
|
|
126
|
+
progress: 100,
|
|
127
|
+
}));
|
|
128
|
+
return res;
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const firmwareCheck = async (reconnectedDevice, device, stripped, postMessage) => {
|
|
132
|
+
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
|
|
133
|
+
device: device.toMessageObject(),
|
|
134
|
+
operation: 'validating',
|
|
135
|
+
progress: 0,
|
|
136
|
+
}));
|
|
137
|
+
const { hash, challenge } = (0, firmware_1.calculateFirmwareHash)(device.features.major_version, stripped, (0, crypto_1.randomBytes)(32));
|
|
138
|
+
const getFirmwareHashResponse = await reconnectedDevice
|
|
139
|
+
.getCommands()
|
|
140
|
+
.typedCall('GetFirmwareHash', 'FirmwareHash', { challenge });
|
|
141
|
+
postMessage((0, events_1.createUiMessage)(events_1.UI.FIRMWARE_PROGRESS, {
|
|
142
|
+
device: device.toMessageObject(),
|
|
143
|
+
operation: 'validating',
|
|
144
|
+
progress: 100,
|
|
145
|
+
}));
|
|
146
|
+
return (getFirmwareHashResponse.message !== 'Unknown message' &&
|
|
147
|
+
getFirmwareHashResponse.message !== 'Unexpected message' &&
|
|
148
|
+
getFirmwareHashResponse.message.hash === hash);
|
|
149
|
+
};
|
|
150
|
+
const onCallFirmwareUpdate = async ({ params, context: { deviceList, postMessage, initDevice, log, abortSignal }, }) => {
|
|
151
|
+
var _a;
|
|
152
|
+
log.debug('onCallFirmwareUpdate with params: ', params);
|
|
153
|
+
const device = await initDevice((_a = params === null || params === void 0 ? void 0 : params.device) === null || _a === void 0 ? void 0 : _a.path);
|
|
154
|
+
if (!device.firmwareRelease) {
|
|
155
|
+
throw constants_1.ERRORS.TypedError('Runtime', 'device.firmwareRelease is not set');
|
|
156
|
+
}
|
|
157
|
+
if (deviceList.allDevices().length > 1) {
|
|
158
|
+
throw constants_1.ERRORS.TypedError('Device_MultipleNotSupported', 'Firmware update allowed with only 1 device connected');
|
|
159
|
+
}
|
|
160
|
+
log.debug('onCallFirmwareUpdate', 'device', device);
|
|
161
|
+
registerEvents(device, postMessage);
|
|
162
|
+
const { manual, upgrade, language } = getInstallationParams(device, params.binary);
|
|
163
|
+
log.debug('onCallFirmwareUpdate', 'installation params', { manual, upgrade, language });
|
|
164
|
+
const binary = params.binary ||
|
|
165
|
+
(await getBinaryHelper(device, params, log, postMessage, device.firmwareRelease.intermediaryVersion));
|
|
166
|
+
const deviceInitiallyConnectedInBootloader = device.features.bootloader_mode;
|
|
167
|
+
const deviceInitiallyConnectedWithoutFirmware = device.features.firmware_present === false;
|
|
168
|
+
let reconnectedDevice = device;
|
|
169
|
+
if (deviceInitiallyConnectedInBootloader) {
|
|
170
|
+
log.warn('onCallFirmwareUpdate', 'device is already in bootloader mode. language will not be updated');
|
|
171
|
+
await device.acquire();
|
|
172
|
+
}
|
|
173
|
+
else if (manual) {
|
|
174
|
+
reconnectedDevice = await waitForReconnectedDevice({ bootloader: true, method: 'manual' }, { deviceList, device, log, postMessage, abortSignal });
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
const rebootParams = upgrade
|
|
178
|
+
? {
|
|
179
|
+
boot_command: constants_1.PROTO.BootCommand.INSTALL_UPGRADE,
|
|
180
|
+
firmware_header: getFwHeader(binary),
|
|
181
|
+
}
|
|
182
|
+
: {};
|
|
183
|
+
await device.acquire();
|
|
184
|
+
const targetLanguage = params.language || device.features.language || 'en-US';
|
|
185
|
+
const languageBlob = language && targetLanguage !== 'en-US'
|
|
186
|
+
? await (0, firmware_1.getLanguage)({
|
|
187
|
+
language: targetLanguage,
|
|
188
|
+
version: device.firmwareRelease.release.version,
|
|
189
|
+
internal_model: device.features.internal_model,
|
|
190
|
+
})
|
|
191
|
+
: null;
|
|
192
|
+
if (!languageBlob) {
|
|
193
|
+
await device.getCommands().typedCall('RebootToBootloader', 'Success', rebootParams);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
let rebootResponse = await device.getCommands().typedCall('RebootToBootloader', ['TranslationDataRequest', 'Success'], { ...rebootParams, language_data_length: languageBlob === null || languageBlob === void 0 ? void 0 : languageBlob.byteLength });
|
|
197
|
+
log.debug('onCallFirmwareUpdate', 'RebootToBootloader response', rebootResponse.message);
|
|
198
|
+
while (languageBlob && rebootResponse.type !== 'Success') {
|
|
199
|
+
const start = rebootResponse.message.data_offset;
|
|
200
|
+
const end = rebootResponse.message.data_offset + rebootResponse.message.data_length;
|
|
201
|
+
const chunk = languageBlob.slice(start, end);
|
|
202
|
+
rebootResponse = await device.getCommands().typedCall('TranslationDataAck', ['TranslationDataRequest', 'Success'], { data_chunk: Buffer.from(chunk).toString('hex') });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
await device.release();
|
|
206
|
+
if (device.features.major_version === 1) {
|
|
207
|
+
await (0, utils_1.createTimeoutPromise)(2000);
|
|
208
|
+
}
|
|
209
|
+
reconnectedDevice = await waitForReconnectedDevice({ bootloader: true, method: 'auto' }, { deviceList, device, log, postMessage, abortSignal });
|
|
210
|
+
}
|
|
211
|
+
const intermediary = !params.binary && device.firmwareRelease.intermediaryVersion;
|
|
212
|
+
await reconnectedDevice.initialize(false, false);
|
|
213
|
+
let stripped = (0, firmware_1.stripFwHeaders)(binary);
|
|
214
|
+
await (0, firmware_1.uploadFirmware)(reconnectedDevice.getCommands().typedCall.bind(reconnectedDevice.getCommands()), postMessage, reconnectedDevice, { payload: !intermediary && (0, firmware_1.shouldStripFwHeaders)(device.features) ? stripped : binary });
|
|
215
|
+
await reconnectedDevice.release();
|
|
216
|
+
if (intermediary) {
|
|
217
|
+
reconnectedDevice = await waitForReconnectedDevice({ bootloader: true, method: 'manual', intermediary: true }, { deviceList, device: reconnectedDevice, log, postMessage, abortSignal });
|
|
218
|
+
stripped = (0, firmware_1.stripFwHeaders)(await getBinaryHelper(reconnectedDevice, params, log, postMessage));
|
|
219
|
+
await reconnectedDevice.initialize(false, false);
|
|
220
|
+
await (0, firmware_1.uploadFirmware)(reconnectedDevice.getCommands().typedCall.bind(reconnectedDevice.getCommands()), postMessage, reconnectedDevice, { payload: stripped });
|
|
221
|
+
await reconnectedDevice.release();
|
|
222
|
+
}
|
|
223
|
+
reconnectedDevice = await waitForReconnectedDevice({ bootloader: false, method: 'wait' }, { deviceList, device: reconnectedDevice, log, postMessage, abortSignal });
|
|
224
|
+
if (reconnectedDevice.atLeast('2.7.0') &&
|
|
225
|
+
deviceInitiallyConnectedWithoutFirmware &&
|
|
226
|
+
params.language) {
|
|
227
|
+
try {
|
|
228
|
+
log.info('onCallFirmwareUpdate', 'changing language for fresh device to: ', params.language);
|
|
229
|
+
await reconnectedDevice.changeLanguage({ language: params.language });
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
log.error('onCallFirmwareUpdate', 'changeLanguage failed silently: ', err);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const checkSupported = reconnectedDevice.atLeast(['1.11.1', '2.5.1']) && !params.binary;
|
|
236
|
+
if (checkSupported) {
|
|
237
|
+
try {
|
|
238
|
+
log.debug('onCallFirmwareUpdate', 'getFirmwareHash supported, proceed with check', stripped);
|
|
239
|
+
const isValid = await firmwareCheck(reconnectedDevice, device, stripped, postMessage);
|
|
240
|
+
await reconnectedDevice.release();
|
|
241
|
+
if (isValid) {
|
|
242
|
+
log.debug('onCallFirmwareUpdate', 'installed fw hash and calculated hash match');
|
|
243
|
+
return { check: 'valid' };
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
return { check: 'mismatch' };
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
return { check: 'other-error', checkError: err.message };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
await reconnectedDevice.release();
|
|
255
|
+
return { check: 'omitted' };
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
exports.onCallFirmwareUpdate = onCallFirmwareUpdate;
|
|
259
|
+
//# sourceMappingURL=onCallFirmwareUpdate.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CoreEventMessage } from '../events';
|
|
2
2
|
import type { Device } from '../types';
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const enhanceMessageWithAnalytics: (message: CoreEventMessage, data: {
|
|
4
4
|
device?: Device;
|
|
5
|
-
}) =>
|
|
5
|
+
}) => CoreEventMessage;
|
|
6
6
|
//# sourceMappingURL=analyticsInfo.d.ts.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.enhanceMessageWithAnalytics = void 0;
|
|
4
4
|
const events_1 = require("../events");
|
|
5
|
-
const
|
|
5
|
+
const enhanceMessageWithAnalytics = (message, data) => {
|
|
6
6
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
7
7
|
switch (message.type) {
|
|
8
8
|
case events_1.UI_REQUEST.REQUEST_CONFIRMATION:
|
|
9
9
|
const { device } = data;
|
|
10
|
-
|
|
10
|
+
return {
|
|
11
11
|
...message,
|
|
12
12
|
payload: {
|
|
13
13
|
...message.payload,
|
|
@@ -27,11 +27,10 @@ const enhancePostMessageWithAnalytics = (callback, message, data) => {
|
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
|
-
}
|
|
31
|
-
break;
|
|
30
|
+
};
|
|
32
31
|
default:
|
|
33
|
-
|
|
32
|
+
return message;
|
|
34
33
|
}
|
|
35
34
|
};
|
|
36
|
-
exports.
|
|
35
|
+
exports.enhanceMessageWithAnalytics = enhanceMessageWithAnalytics;
|
|
37
36
|
//# sourceMappingURL=analyticsInfo.js.map
|
|
@@ -25,7 +25,7 @@ exports.DeviceAuthenticityConfig = schema_utils_1.Type.Intersect([
|
|
|
25
25
|
]);
|
|
26
26
|
exports.deviceAuthenticityConfig = {
|
|
27
27
|
version: 1,
|
|
28
|
-
timestamp: '
|
|
28
|
+
timestamp: '2024-05-10T12:00:00+00:00',
|
|
29
29
|
T2B1: {
|
|
30
30
|
rootPubKeys: [
|
|
31
31
|
'04ca97480ac0d7b1e6efafe518cd433cec2bf8ab9822d76eafd34363b55d63e60380bff20acc75cde03cffcb50ab6f8ce70c878e37ebc58ff7cca0a83b16b15fa5',
|
|
@@ -46,6 +46,12 @@ exports.deviceAuthenticityConfig = {
|
|
|
46
46
|
'04c99f57eaaca8db0245a46dba5288a4c0b0d6acdd1346feef7770ec6b88d28d6640ee19c3f6d984e8fcfceda11b1e4accefda32b950dcd1785fbd16c2e45493a3',
|
|
47
47
|
'049c288f4de8a239be83955ed260f40c1a4126fb7dc513601dde4cb11f7363d6a259e73cb1bd9283a450ae608d1832c5fd0cbd9526c0285e720fa45494cae981fd',
|
|
48
48
|
'04ac1815177cc1f07700e5f18c05522427413f404bacc987eb1cf9d86f96b9e0cc53ef5941eafd483102eea321205d7dd9271ac2d0fca75a9a43deb824b51f1596',
|
|
49
|
+
'049f91ac8c7dac26fa7eb82ff3fb8c6d24978bbaeed1adb0751342a8c4c88152817d50bd0b4c16d8fb85bf12f46dca0674a398aeecbb3d1a01236cd3eb39d24c55',
|
|
50
|
+
'04c5225b6d8b84401c408ad0a5aa47888e9087451a2ca4440e46efed5765fd2f5bf8f068e1cfea18dddfc5b47b19076ce0a84fbcf7269f9578d9b978679dea4189',
|
|
51
|
+
'04e349de85981f8e7d95ca4b44346924a9df62875971cfc5e21fc042c3a8fb3e1ddfeac139c15fcf3f7968242a418fc80e92c98f5aef39672b13b60d0b2335c84c',
|
|
52
|
+
'04d7ddaf7e17a678bef305950f0f9d74b90553d8502fd02c439f07ac7ea494e9e0519a1c5782bf23be058162e706057d3b241d507f89b9e5518e3696a92128fa6d',
|
|
53
|
+
'0488cf1dbadb18df0a094da837b3eeb0c85489cc21e7c2b94f8f4df207edccfddbb58e428d9a6ce1e42081c38665d134c7ee6f1f524688ce7444bc1d1340a8b1f1',
|
|
54
|
+
'04ff0c6e817d7c00a0912cf1d293e4d3a8c25403dca4e8ced5e7323352e34604725ad67739d1b4bf538a3864e95d8311ebc91d522b1603da94061e82535edced56',
|
|
49
55
|
],
|
|
50
56
|
debug: {
|
|
51
57
|
rootPubKeys: [
|
|
@@ -67,12 +73,10 @@ exports.deviceAuthenticityConfig = {
|
|
|
67
73
|
],
|
|
68
74
|
debug: {
|
|
69
75
|
rootPubKeys: [
|
|
70
|
-
'
|
|
76
|
+
'04e48b69cd7962068d3cca3bcc6b1747ef496c1e28b5529e34ad7295215ea161dbe8fb08ae0479568f9d2cb07630cb3e52f4af0692102da5873559e45e9fa72959',
|
|
71
77
|
],
|
|
72
78
|
caPubKeys: [
|
|
73
79
|
'04829e8965018feb542e9236c9b2ce08f864a55ed9183d0259564f0e05345b04676a0bef36c59d21d3c24868b5601f0b1193a6bfcf6d814e1cfb79c2256a05e953',
|
|
74
|
-
'046f64eff0dfa3ceeae9708a3881fc09a3dae62198559d022d120e96edc168f3991a9e9b016635a0d43997ee55d8c2b37d969e8abc84e75c791ec911108b52f3c7',
|
|
75
|
-
'041260c3c1fd4ddfc97ba19732d5dcbe6efab61d58af83281b95d6cdb30606bf08f0b817eb6db2825b5ce32d0cc2c275b7eadcedaa1805f00b3f5a11668b6c5cb5',
|
|
76
80
|
],
|
|
77
81
|
},
|
|
78
82
|
},
|
package/lib/data/firmwareInfo.js
CHANGED
|
@@ -117,7 +117,7 @@ const getInfo = ({ features, releases }) => {
|
|
|
117
117
|
isRequired: isRequired(changelog),
|
|
118
118
|
isNewer: isNewerResult,
|
|
119
119
|
intermediaryVersion,
|
|
120
|
-
translations: isNewerResult ? prevRelease.translations : release.translations,
|
|
120
|
+
translations: isNewerResult ? prevRelease === null || prevRelease === void 0 ? void 0 : prevRelease.translations : release === null || release === void 0 ? void 0 : release.translations,
|
|
121
121
|
};
|
|
122
122
|
};
|
|
123
123
|
exports.getInfo = getInfo;
|
package/lib/data/version.d.ts
CHANGED
package/lib/data/version.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DEFAULT_DOMAIN = exports.VERSION = void 0;
|
|
4
|
-
exports.VERSION = '9.2.
|
|
4
|
+
exports.VERSION = '9.2.4-beta.1';
|
|
5
5
|
const versionN = exports.VERSION.split('.').map(s => parseInt(s, 10));
|
|
6
6
|
exports.DEFAULT_DOMAIN = `https://connect.trezor.io/${versionN[0]}/`;
|
|
7
7
|
//# sourceMappingURL=version.js.map
|
package/lib/device/Device.d.ts
CHANGED
|
@@ -102,7 +102,7 @@ export declare class Device extends TypedEmitter<DeviceEvents> {
|
|
|
102
102
|
getDevicePath(): string;
|
|
103
103
|
isT1(): boolean;
|
|
104
104
|
hasUnexpectedMode(allow: string[], require: string[]): "ui-device_bootloader_mode" | "ui-device_not_in_bootloader_mode" | "ui-device_not_initialized" | "ui-device_seedless" | null;
|
|
105
|
-
dispose(): import("@trezor/transport/lib/types").AbortableCall<void, "Network request failed" | "Wrong result type." | "device disconnected during action" | "unexpected error" | "Aborted by timeout" | "Aborted by signal" | "This transport can not be used in this environment" | "device not found" | "Unable to open device" | "wrong previous session" | "session not found"> | undefined
|
|
105
|
+
dispose(): Promise<import("@trezor/transport/lib/types").AbortableCall<void, "Network request failed" | "Wrong result type." | "device disconnected during action" | "unexpected error" | "Aborted by timeout" | "Aborted by signal" | "This transport can not be used in this environment" | "device not found" | "Unable to open device" | "wrong previous session" | "session not found"> | undefined>;
|
|
106
106
|
getMode(): "normal" | "bootloader" | "initialize" | "seedless";
|
|
107
107
|
toMessageObject(): DeviceTyped;
|
|
108
108
|
legacyForceRelease(): Promise<void>;
|
package/lib/device/Device.js
CHANGED
|
@@ -491,12 +491,12 @@ class Device extends utils_1.TypedEmitter {
|
|
|
491
491
|
}
|
|
492
492
|
return null;
|
|
493
493
|
}
|
|
494
|
-
dispose() {
|
|
494
|
+
async dispose() {
|
|
495
495
|
this.removeAllListeners();
|
|
496
496
|
if (this.isUsedHere() && this.activitySessionID) {
|
|
497
497
|
try {
|
|
498
498
|
if (this.commands) {
|
|
499
|
-
this.commands.cancel();
|
|
499
|
+
await this.commands.cancel();
|
|
500
500
|
}
|
|
501
501
|
return this.transport.release({
|
|
502
502
|
session: this.activitySessionID,
|
|
@@ -43,8 +43,8 @@ export declare class DeviceCommands {
|
|
|
43
43
|
};
|
|
44
44
|
xpub: string;
|
|
45
45
|
}>;
|
|
46
|
-
getHDNode(params: Messages.GetPublicKey, options
|
|
47
|
-
coinInfo
|
|
46
|
+
getHDNode(params: Messages.GetPublicKey, options: {
|
|
47
|
+
coinInfo: BitcoinNetworkInfo;
|
|
48
48
|
validation?: boolean;
|
|
49
49
|
unlockPath?: Messages.UnlockPath;
|
|
50
50
|
}): Promise<{
|
|
@@ -59,18 +59,6 @@ export declare class DeviceCommands {
|
|
|
59
59
|
childNum: number;
|
|
60
60
|
xpub: string;
|
|
61
61
|
}>;
|
|
62
|
-
getBitcoinHDNode(path: number[], coinInfo?: BitcoinNetworkInfo, validation?: boolean): Promise<{
|
|
63
|
-
xpubSegwit?: string | undefined;
|
|
64
|
-
descriptorChecksum?: string | undefined;
|
|
65
|
-
path: number[];
|
|
66
|
-
publicKey: string;
|
|
67
|
-
serializedPath: string;
|
|
68
|
-
depth: number;
|
|
69
|
-
fingerprint: number;
|
|
70
|
-
chainCode: string;
|
|
71
|
-
childNum: number;
|
|
72
|
-
xpub: string;
|
|
73
|
-
}>;
|
|
74
62
|
getAddress({ address_n, show_display, multisig, script_type, chunkify }: Messages.GetAddress, coinInfo: BitcoinNetworkInfo): Promise<{
|
|
75
63
|
path: number[];
|
|
76
64
|
serializedPath: string;
|
|
@@ -67,13 +67,10 @@ class DeviceCommands {
|
|
|
67
67
|
});
|
|
68
68
|
return response.message;
|
|
69
69
|
}
|
|
70
|
-
async getHDNode(params, options
|
|
70
|
+
async getHDNode(params, options) {
|
|
71
71
|
const path = params.address_n;
|
|
72
72
|
const { coinInfo, unlockPath } = options;
|
|
73
73
|
const validation = typeof options.validation === 'boolean' ? options.validation : true;
|
|
74
|
-
if (!this.device.atLeast(['1.7.2', '2.0.10']) || !coinInfo) {
|
|
75
|
-
return this.getBitcoinHDNode(path, coinInfo);
|
|
76
|
-
}
|
|
77
74
|
let network = null;
|
|
78
75
|
if (!params.script_type) {
|
|
79
76
|
params.script_type = (0, pathUtils_1.getScriptType)(path);
|
|
@@ -125,42 +122,6 @@ class DeviceCommands {
|
|
|
125
122
|
}
|
|
126
123
|
return response;
|
|
127
124
|
}
|
|
128
|
-
async getBitcoinHDNode(path, coinInfo, validation = true) {
|
|
129
|
-
let publicKey;
|
|
130
|
-
if (!validation) {
|
|
131
|
-
publicKey = await this.getPublicKey({ address_n: path });
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
const suffix = 0;
|
|
135
|
-
const childPath = path.concat([suffix]);
|
|
136
|
-
const resKey = await this.getPublicKey({ address_n: path });
|
|
137
|
-
const childKey = await this.getPublicKey({ address_n: childPath });
|
|
138
|
-
publicKey = hdnodeUtils.xpubDerive(resKey, childKey, suffix);
|
|
139
|
-
}
|
|
140
|
-
const response = {
|
|
141
|
-
path,
|
|
142
|
-
serializedPath: (0, pathUtils_1.getSerializedPath)(path),
|
|
143
|
-
childNum: publicKey.node.child_num,
|
|
144
|
-
xpub: coinInfo
|
|
145
|
-
? hdnodeUtils.convertBitcoinXpub(publicKey.xpub, coinInfo.network)
|
|
146
|
-
: publicKey.xpub,
|
|
147
|
-
chainCode: publicKey.node.chain_code,
|
|
148
|
-
publicKey: publicKey.node.public_key,
|
|
149
|
-
fingerprint: publicKey.node.fingerprint,
|
|
150
|
-
depth: publicKey.node.depth,
|
|
151
|
-
};
|
|
152
|
-
if (coinInfo) {
|
|
153
|
-
const bech32Network = (0, coinInfo_1.getBech32Network)(coinInfo);
|
|
154
|
-
const segwitNetwork = (0, coinInfo_1.getSegwitNetwork)(coinInfo);
|
|
155
|
-
if (bech32Network && (0, pathUtils_1.isBech32Path)(path)) {
|
|
156
|
-
response.xpubSegwit = hdnodeUtils.convertBitcoinXpub(publicKey.xpub, bech32Network);
|
|
157
|
-
}
|
|
158
|
-
else if (segwitNetwork && (0, pathUtils_1.isSegwitPath)(path)) {
|
|
159
|
-
response.xpubSegwit = hdnodeUtils.convertBitcoinXpub(publicKey.xpub, segwitNetwork);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return response;
|
|
163
|
-
}
|
|
164
125
|
async getAddress({ address_n, show_display, multisig, script_type, chunkify }, coinInfo) {
|
|
165
126
|
if (!script_type) {
|
|
166
127
|
script_type = (0, pathUtils_1.getScriptType)(address_n);
|
|
@@ -203,9 +164,6 @@ class DeviceCommands {
|
|
|
203
164
|
};
|
|
204
165
|
}
|
|
205
166
|
async ethereumGetPublicKey({ address_n, show_display, }) {
|
|
206
|
-
if (!this.device.atLeast(['1.8.1', '2.1.0'])) {
|
|
207
|
-
return this.getHDNode({ address_n });
|
|
208
|
-
}
|
|
209
167
|
const suffix = 0;
|
|
210
168
|
const childPath = address_n.concat([suffix]);
|
|
211
169
|
const resKey = await this.typedCall('EthereumGetPublicKey', 'EthereumPublicKey', {
|
|
@@ -42,7 +42,7 @@ export declare class DeviceList extends TypedEmitter<DeviceListEvents> {
|
|
|
42
42
|
length(): number;
|
|
43
43
|
transportType(): "BridgeTransport" | "NodeUsbTransport" | "WebUsbTransport" | "UdpTransport";
|
|
44
44
|
getTransportInfo(): TransportInfo;
|
|
45
|
-
dispose():
|
|
45
|
+
dispose(): void;
|
|
46
46
|
disconnectDevices(): void;
|
|
47
47
|
enumerate(): Promise<void>;
|
|
48
48
|
addAuthPenalty(device: Device): void;
|
package/lib/device/DeviceList.js
CHANGED
|
@@ -90,14 +90,24 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
92
|
this.transport.on(transport_1.TRANSPORT.UPDATE, diff => {
|
|
93
|
+
diff.disconnected.forEach(descriptor => {
|
|
94
|
+
const path = descriptor.path.toString();
|
|
95
|
+
const device = this.devices[path];
|
|
96
|
+
if (device) {
|
|
97
|
+
device.disconnect();
|
|
98
|
+
delete this.devices[path];
|
|
99
|
+
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
100
|
+
}
|
|
101
|
+
});
|
|
93
102
|
diff.connected.forEach(async (descriptor) => {
|
|
94
103
|
const path = descriptor.path.toString();
|
|
104
|
+
this.creatingDevicesDescriptors[path] = descriptor;
|
|
95
105
|
const priority = DataManager_1.DataManager.getSettings('priority');
|
|
96
106
|
const penalty = this.getAuthPenalty();
|
|
97
107
|
if (priority || penalty) {
|
|
98
108
|
await (0, promiseUtils_1.resolveAfter)(501 + penalty + 100 * priority, null).promise;
|
|
99
109
|
}
|
|
100
|
-
if (
|
|
110
|
+
if (this.creatingDevicesDescriptors[path].session == null) {
|
|
101
111
|
await this._createAndSaveDevice(descriptor);
|
|
102
112
|
}
|
|
103
113
|
else {
|
|
@@ -158,20 +168,13 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
158
168
|
}
|
|
159
169
|
});
|
|
160
170
|
});
|
|
161
|
-
diff.disconnected.forEach(descriptor => {
|
|
162
|
-
const path = descriptor.path.toString();
|
|
163
|
-
const device = this.devices[path];
|
|
164
|
-
if (device) {
|
|
165
|
-
device.disconnect();
|
|
166
|
-
delete this.devices[path];
|
|
167
|
-
this.emit(events_1.DEVICE.DISCONNECT, device.toMessageObject());
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
171
|
diff.descriptors.forEach(d => {
|
|
172
|
+
this.creatingDevicesDescriptors[d.path] = d;
|
|
171
173
|
if (this.devices[d.path]) {
|
|
172
174
|
this.devices[d.path].originalDescriptor = {
|
|
173
175
|
session: d.session,
|
|
174
176
|
path: d.path,
|
|
177
|
+
product: d.product,
|
|
175
178
|
};
|
|
176
179
|
}
|
|
177
180
|
});
|
|
@@ -265,13 +268,14 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
265
268
|
outdated: this.transport.isOutdated,
|
|
266
269
|
};
|
|
267
270
|
}
|
|
268
|
-
|
|
271
|
+
dispose() {
|
|
269
272
|
this.removeAllListeners();
|
|
270
273
|
if (autoResolveTransportEventTimeout) {
|
|
271
274
|
clearTimeout(autoResolveTransportEventTimeout);
|
|
272
275
|
}
|
|
273
|
-
|
|
274
|
-
|
|
276
|
+
Promise.all(this.allDevices().map(device => device.dispose())).then(() => {
|
|
277
|
+
this.transport.stop();
|
|
278
|
+
});
|
|
275
279
|
}
|
|
276
280
|
disconnectDevices() {
|
|
277
281
|
this.allDevices().forEach(device => {
|
|
@@ -288,6 +292,7 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
288
292
|
this.devices[d.path].originalDescriptor = {
|
|
289
293
|
session: d.session,
|
|
290
294
|
path: d.path,
|
|
295
|
+
product: d.product,
|
|
291
296
|
};
|
|
292
297
|
this.devices[d.path].activitySessionID = d.session;
|
|
293
298
|
}
|
|
@@ -315,7 +320,6 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
315
320
|
async handle(descriptor) {
|
|
316
321
|
var _a;
|
|
317
322
|
const path = descriptor.path.toString();
|
|
318
|
-
this.creatingDevicesDescriptors[path] = descriptor;
|
|
319
323
|
try {
|
|
320
324
|
await this._takeAndCreateDevice(descriptor);
|
|
321
325
|
}
|
|
@@ -324,7 +328,8 @@ class DeviceList extends utils_1.TypedEmitter {
|
|
|
324
328
|
if (error.code === 'Device_NotFound' ||
|
|
325
329
|
error.message === transport_1.TRANSPORT_ERROR.DEVICE_NOT_FOUND ||
|
|
326
330
|
error.message === transport_1.TRANSPORT_ERROR.DEVICE_DISCONNECTED_DURING_ACTION ||
|
|
327
|
-
error.message === transport_1.TRANSPORT_ERROR.UNEXPECTED_ERROR
|
|
331
|
+
error.message === transport_1.TRANSPORT_ERROR.UNEXPECTED_ERROR ||
|
|
332
|
+
error.message === transport_1.TRANSPORT_ERROR.HTTP_ERROR) {
|
|
328
333
|
delete this.devices[path];
|
|
329
334
|
}
|
|
330
335
|
else if (error.message === transport_1.TRANSPORT_ERROR.SESSION_WRONG_PREVIOUS) {
|
package/lib/events/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare const UI: {
|
|
|
33
33
|
readonly FIRMWARE_NOT_COMPATIBLE: "ui-device_firmware_not_compatible";
|
|
34
34
|
readonly FIRMWARE_NOT_INSTALLED: "ui-device_firmware_not_installed";
|
|
35
35
|
readonly FIRMWARE_PROGRESS: "ui-firmware-progress";
|
|
36
|
+
readonly FIRMWARE_RECONNECT: "ui-firmware_reconnect";
|
|
36
37
|
readonly DEVICE_NEEDS_BACKUP: "ui-device_needs_backup";
|
|
37
38
|
readonly REQUEST_UI_WINDOW: "ui-request_window";
|
|
38
39
|
readonly CLOSE_UI_WINDOW: "ui-close_window";
|