@onekeyfe/hd-core 1.2.0-alpha.23 → 1.2.0-alpha.24

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.
Files changed (131) hide show
  1. package/__tests__/DeviceCommands.test.ts +35 -0
  2. package/__tests__/connectSettings.test.ts +5 -47
  3. package/__tests__/device-lifecycle-events.test.ts +59 -0
  4. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +30 -39
  5. package/__tests__/open-wallet-session.test.ts +192 -129
  6. package/__tests__/protocol-v2-ping.test.ts +28 -0
  7. package/__tests__/protocol-v2.test.ts +338 -376
  8. package/__tests__/public-pro2-api-boundary.test.ts +22 -0
  9. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  10. package/dist/api/FirmwareUpdateV2.d.ts +0 -11
  11. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  12. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  13. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  14. package/dist/api/FirmwareUpdateV4.d.ts +5 -21
  15. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  16. package/dist/api/OpenWalletSession.d.ts +1 -8
  17. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  18. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  19. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  20. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -7
  21. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  22. package/dist/api/firmware/getBinary.d.ts +0 -7
  23. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  24. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  25. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  26. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  27. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  28. package/dist/api/index.d.ts +1 -0
  29. package/dist/api/index.d.ts.map +1 -1
  30. package/dist/api/protocol-v2/Ping.d.ts +2 -0
  31. package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
  32. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  33. package/dist/core/index.d.ts.map +1 -1
  34. package/dist/data-manager/DataManager.d.ts +0 -1
  35. package/dist/data-manager/DataManager.d.ts.map +1 -1
  36. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  37. package/dist/device/Device.d.ts.map +1 -1
  38. package/dist/device/DeviceCommands.d.ts.map +1 -1
  39. package/dist/index.d.ts +89 -273
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +783 -2443
  42. package/dist/inject.d.ts.map +1 -1
  43. package/dist/lowLevelInject.d.ts.map +1 -1
  44. package/dist/protocols/protocol-v2/unlockRetry.d.ts +2 -3
  45. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
  46. package/dist/protocols/protocol-v2/walletSession.d.ts +12 -0
  47. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  48. package/dist/topLevelInject.d.ts.map +1 -1
  49. package/dist/types/api/checkAllFirmwareRelease.d.ts +0 -3
  50. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  51. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  52. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  53. package/dist/types/api/export.d.ts +1 -4
  54. package/dist/types/api/export.d.ts.map +1 -1
  55. package/dist/types/api/firmwareUpdate.d.ts +0 -69
  56. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  57. package/dist/types/api/index.d.ts +4 -10
  58. package/dist/types/api/index.d.ts.map +1 -1
  59. package/dist/types/api/openWalletSession.d.ts +0 -12
  60. package/dist/types/api/openWalletSession.d.ts.map +1 -1
  61. package/dist/types/api/protocolV2.d.ts +4 -0
  62. package/dist/types/api/protocolV2.d.ts.map +1 -1
  63. package/dist/types/settings.d.ts +0 -13
  64. package/dist/types/settings.d.ts.map +1 -1
  65. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  66. package/dist/utils/patch.d.ts +1 -1
  67. package/dist/utils/patch.d.ts.map +1 -1
  68. package/package.json +4 -4
  69. package/src/api/CheckAllFirmwareRelease.ts +3 -23
  70. package/src/api/FirmwareUpdateV2.ts +120 -292
  71. package/src/api/FirmwareUpdateV3.ts +55 -256
  72. package/src/api/FirmwareUpdateV4.ts +297 -757
  73. package/src/api/OpenWalletSession.ts +23 -86
  74. package/src/api/device/DeviceUpdateBootloader.ts +6 -122
  75. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +0 -50
  76. package/src/api/firmware/updateBootloader.ts +4 -19
  77. package/src/api/firmware/uploadFirmware.ts +22 -140
  78. package/src/api/index.ts +1 -0
  79. package/src/api/protocol-v2/Ping.ts +32 -1
  80. package/src/core/index.ts +39 -7
  81. package/src/data/messages/messages-protocol-v2.json +33 -1
  82. package/src/data-manager/DataManager.ts +33 -33
  83. package/src/data-manager/connectSettings.ts +0 -11
  84. package/src/device/Device.ts +7 -9
  85. package/src/device/DeviceCommands.ts +19 -0
  86. package/src/index.ts +0 -5
  87. package/src/inject.ts +4 -22
  88. package/src/lowLevelInject.ts +1 -5
  89. package/src/protocols/protocol-v2/unlockRetry.ts +20 -3
  90. package/src/protocols/protocol-v2/walletSession.ts +26 -8
  91. package/src/topLevelInject.ts +1 -5
  92. package/src/types/api/checkAllFirmwareRelease.ts +0 -3
  93. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  94. package/src/types/api/export.ts +0 -18
  95. package/src/types/api/firmwareUpdate.ts +0 -76
  96. package/src/types/api/index.ts +3 -14
  97. package/src/types/api/openWalletSession.ts +0 -19
  98. package/src/types/api/protocolV2.ts +10 -0
  99. package/src/types/settings.ts +0 -13
  100. package/src/utils/deviceInfoUtils.ts +15 -3
  101. package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -86
  102. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  103. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  104. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  105. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -326
  106. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
  107. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  108. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
  109. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  110. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  111. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  112. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  113. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  114. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -23
  115. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  116. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -30
  117. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  118. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  119. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  120. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -27
  121. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  122. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  123. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  124. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  125. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  126. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  127. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -621
  128. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -392
  129. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  130. package/src/types/api/firmwareUpdatePlan.ts +0 -36
  131. package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
package/dist/index.js CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var hdShared = require('@onekeyfe/hd-shared');
6
- var utils = require('@noble/hashes/utils');
7
- var sha256 = require('@noble/hashes/sha256');
8
5
  var semver = require('semver');
9
6
  var hdTransport = require('@onekeyfe/hd-transport');
7
+ var hdShared = require('@onekeyfe/hd-shared');
10
8
  var axios = require('axios');
11
9
  var lodash = require('lodash');
12
10
  var ByteBuffer = require('bytebuffer');
13
11
  var BigNumber = require('bignumber.js');
12
+ var utils = require('@noble/hashes/utils');
14
13
  var blake2s = require('@noble/hashes/blake2s');
14
+ var sha256 = require('@noble/hashes/sha256');
15
15
  var JSZip = require('jszip');
16
16
  var sha3 = require('@noble/hashes/sha3');
17
17
  var blake2b = require('@noble/hashes/blake2b');
@@ -87,1117 +87,6 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
87
87
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
88
88
  };
89
89
 
90
- const getFirmwareUpdateCapabilities = () => ({
91
- planSchemaVersion: 2,
92
- preparedPlanSchemaVersion: 2,
93
- hostBindingProtocolVersion: 2,
94
- manifestModes: ['external-only', 'sdk-managed'],
95
- supportsArtifactReader: true,
96
- });
97
-
98
- const MAX_FIRMWARE_ARTIFACT_READ_BYTES = 256 * 1024;
99
- const artifactError = (code, message) => {
100
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
101
- firmwareUpdateCode: code,
102
- });
103
- };
104
- const assertSafeSize = (value, name) => {
105
- if (!Number.isSafeInteger(value) || value <= 0) {
106
- artifactError('FirmwareArtifactReceiptMismatch', `${name} must be a positive safe integer`);
107
- }
108
- };
109
- const assertFirmwareArtifactReference = (artifact) => {
110
- if (!artifact ||
111
- typeof artifact.artifactRef !== 'string' ||
112
- artifact.artifactRef.length === 0 ||
113
- artifact.artifactRef.length > 160 ||
114
- artifact.artifactRef.includes('/') ||
115
- artifact.artifactRef.includes('\\')) {
116
- artifactError('FirmwareArtifactReceiptMismatch', 'Firmware artifactRef must be an opaque identifier');
117
- }
118
- assertSafeSize(artifact.size, 'Firmware artifact size');
119
- if (typeof artifact.sha256 !== 'string' || !/^[a-f0-9]{64}$/i.test(artifact.sha256)) {
120
- artifactError('FirmwareArtifactReceiptMismatch', 'Firmware artifact sha256 must be a 32-byte hexadecimal digest');
121
- }
122
- return artifact;
123
- };
124
- const assertFirmwareArtifactRead = (size, offset, length) => {
125
- if (!Number.isSafeInteger(offset) ||
126
- offset < 0 ||
127
- offset >= size ||
128
- !Number.isSafeInteger(length) ||
129
- length <= 0 ||
130
- offset + length > size) {
131
- artifactError('FirmwareArtifactReadOutOfBounds', `Firmware artifact read is outside size ${size}: offset=${offset}, length=${length}`);
132
- }
133
- if (length > MAX_FIRMWARE_ARTIFACT_READ_BYTES) {
134
- artifactError('FirmwareArtifactReadTooLarge', `Firmware artifact read length ${length} exceeds ${MAX_FIRMWARE_ARTIFACT_READ_BYTES}`);
135
- }
136
- };
137
- const createMemoryFirmwareByteSource = (binary) => {
138
- let bytes = new Uint8Array(binary);
139
- const { byteLength: size } = binary;
140
- assertSafeSize(size, 'Firmware binary size');
141
- return {
142
- size,
143
- readAt: (offset, length) => {
144
- if (!bytes) {
145
- return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware byte source is closed', {
146
- firmwareUpdateCode: 'FirmwareArtifactReaderInvalid',
147
- }));
148
- }
149
- assertFirmwareArtifactRead(size, offset, length);
150
- return Promise.resolve(bytes.slice(offset, offset + length).buffer);
151
- },
152
- close: () => {
153
- bytes = null;
154
- return Promise.resolve();
155
- },
156
- };
157
- };
158
- class ReaderFirmwareByteSource {
159
- constructor(reader, readerId, size) {
160
- this.reader = reader;
161
- this.readerId = readerId;
162
- this.closed = false;
163
- this.reading = false;
164
- this.size = size;
165
- }
166
- static open(artifact, reader) {
167
- var _a;
168
- return __awaiter(this, void 0, void 0, function* () {
169
- const opened = yield reader.open({ artifactRef: artifact.artifactRef });
170
- if (!opened ||
171
- typeof opened.readerId !== 'string' ||
172
- opened.readerId.length === 0 ||
173
- !Number.isSafeInteger(opened.size) ||
174
- opened.size !== artifact.size) {
175
- if (opened === null || opened === void 0 ? void 0 : opened.readerId) {
176
- yield reader.close({ readerId: opened.readerId }).catch(() => undefined);
177
- }
178
- return artifactError('FirmwareArtifactReceiptMismatch', `Firmware artifact opened with size ${(_a = opened === null || opened === void 0 ? void 0 : opened.size) !== null && _a !== void 0 ? _a : 'unknown'}, expected ${artifact.size}`);
179
- }
180
- return new ReaderFirmwareByteSource(reader, opened.readerId, opened.size);
181
- });
182
- }
183
- readAt(offset, length) {
184
- return __awaiter(this, void 0, void 0, function* () {
185
- if (this.closed) {
186
- return artifactError('FirmwareArtifactReaderInvalid', 'Firmware artifact reader is closed');
187
- }
188
- if (this.reading) {
189
- return artifactError('FirmwareArtifactReaderInvalid', 'Firmware artifact reader only permits one in-flight read');
190
- }
191
- assertFirmwareArtifactRead(this.size, offset, length);
192
- this.reading = true;
193
- try {
194
- const result = yield this.reader.read({
195
- readerId: this.readerId,
196
- offset,
197
- length,
198
- });
199
- const expectedEof = offset + length === this.size;
200
- if (!result ||
201
- !(result.data instanceof ArrayBuffer) ||
202
- result.data.byteLength !== length ||
203
- result.bytesRead !== length ||
204
- result.eof !== expectedEof) {
205
- return artifactError('FirmwareArtifactReaderInvalid', 'Firmware artifact reader returned an invalid read result');
206
- }
207
- return result.data;
208
- }
209
- finally {
210
- this.reading = false;
211
- }
212
- });
213
- }
214
- close() {
215
- return __awaiter(this, void 0, void 0, function* () {
216
- if (this.closed) {
217
- return;
218
- }
219
- this.closed = true;
220
- yield this.reader.close({ readerId: this.readerId });
221
- });
222
- }
223
- }
224
- const openFirmwareByteSource = ({ binary, artifact, reader, }) => __awaiter(void 0, void 0, void 0, function* () {
225
- if (binary && artifact) {
226
- return artifactError('FirmwareArtifactReceiptMismatch', 'Firmware input must not contain both binary and artifactRef');
227
- }
228
- if (binary) {
229
- return createMemoryFirmwareByteSource(binary);
230
- }
231
- if (!artifact) {
232
- return null;
233
- }
234
- assertFirmwareArtifactReference(artifact);
235
- if (!reader) {
236
- return artifactError('FirmwareArtifactReaderInvalid', 'Firmware artifact reader is required for artifactRef input');
237
- }
238
- return ReaderFirmwareByteSource.open(artifact, reader);
239
- });
240
- const readFirmwareByteSourceFully = (source) => __awaiter(void 0, void 0, void 0, function* () {
241
- const output = new Uint8Array(source.size);
242
- let offset = 0;
243
- while (offset < source.size) {
244
- const length = Math.min(MAX_FIRMWARE_ARTIFACT_READ_BYTES, source.size - offset);
245
- output.set(new Uint8Array(yield source.readAt(offset, length)), offset);
246
- offset += length;
247
- }
248
- return output.buffer;
249
- });
250
- const writeFirmwareByteSource = ({ source, chunkSize, write, }) => __awaiter(void 0, void 0, void 0, function* () {
251
- if (!Number.isSafeInteger(chunkSize) ||
252
- chunkSize <= 0 ||
253
- chunkSize > MAX_FIRMWARE_ARTIFACT_READ_BYTES) {
254
- return artifactError('FirmwareArtifactReadTooLarge', `Firmware artifact chunk size must be between 1 and ${MAX_FIRMWARE_ARTIFACT_READ_BYTES}`);
255
- }
256
- let offset = 0;
257
- while (offset < source.size) {
258
- const length = Math.min(chunkSize, source.size - offset);
259
- const data = yield source.readAt(offset, length);
260
- const processed = yield write({
261
- data,
262
- sourceOffset: offset,
263
- length,
264
- first: offset === 0,
265
- });
266
- if (processed !== length) {
267
- return artifactError('FirmwareArtifactReaderInvalid', `Firmware artifact writer processed ${processed} bytes, expected ${length}`);
268
- }
269
- offset += length;
270
- }
271
- return offset;
272
- });
273
-
274
- exports.EOneKeyDeviceMode = void 0;
275
- (function (EOneKeyDeviceMode) {
276
- EOneKeyDeviceMode["bootloader"] = "bootloader";
277
- EOneKeyDeviceMode["normal"] = "normal";
278
- EOneKeyDeviceMode["notInitialized"] = "notInitialized";
279
- EOneKeyDeviceMode["backupMode"] = "backupMode";
280
- })(exports.EOneKeyDeviceMode || (exports.EOneKeyDeviceMode = {}));
281
- const DeviceModelToTypes = {
282
- model_mini: [
283
- hdShared.EDeviceType.Classic,
284
- hdShared.EDeviceType.Classic1s,
285
- hdShared.EDeviceType.ClassicPure,
286
- hdShared.EDeviceType.Mini,
287
- ],
288
- model_touch: [hdShared.EDeviceType.Touch, hdShared.EDeviceType.Pro],
289
- model_classic: [hdShared.EDeviceType.Classic, hdShared.EDeviceType.Classic1s, hdShared.EDeviceType.ClassicPure],
290
- model_classic1s: [hdShared.EDeviceType.Classic1s, hdShared.EDeviceType.ClassicPure],
291
- };
292
- const DeviceTypeToModels = {
293
- [hdShared.EDeviceType.Classic]: ['model_classic', 'model_mini'],
294
- [hdShared.EDeviceType.Classic1s]: ['model_classic', 'model_mini', 'model_classic1s'],
295
- [hdShared.EDeviceType.ClassicPure]: ['model_classic', 'model_mini', 'model_classic1s'],
296
- [hdShared.EDeviceType.Mini]: ['model_mini'],
297
- [hdShared.EDeviceType.Touch]: ['model_touch'],
298
- [hdShared.EDeviceType.Pro]: ['model_touch'],
299
- [hdShared.EDeviceType.Pro2]: [],
300
- [hdShared.EDeviceType.Unknown]: [],
301
- };
302
-
303
- const asCompatibleFeatures = (features) => features;
304
- const firstNonEmptyString = (...values) => values.find(value => typeof value === 'string' && value.length > 0);
305
- const firstMeaningfulVersion$1 = (...versions) => { var _a; return (_a = versions.find(version => Boolean(version && version !== '0.0.0'))) !== null && _a !== void 0 ? _a : null; };
306
- const versionFromParts = (major, minor, patch) => [major, minor, patch].map(part => Number(part) || 0).join('.');
307
- const resolveDeviceSerialNo = (features) => {
308
- var _a;
309
- if (!features)
310
- return '';
311
- const compatible = asCompatibleFeatures(features);
312
- return ((_a = firstNonEmptyString(compatible.serialNo, compatible.onekey_serial_no, compatible.onekey_serial, compatible.serial_no)) !== null && _a !== void 0 ? _a : '');
313
- };
314
- const resolveDeviceType = (features) => {
315
- var _a, _b, _c, _d;
316
- if (!features || typeof features !== 'object') {
317
- return hdShared.EDeviceType.Unknown;
318
- }
319
- const compatible = asCompatibleFeatures(features);
320
- if (compatible.deviceType && compatible.deviceType !== hdShared.EDeviceType.Unknown) {
321
- return compatible.deviceType;
322
- }
323
- switch ((_a = compatible.onekey_device_type) === null || _a === void 0 ? void 0 : _a.toString().toUpperCase()) {
324
- case 'CLASSIC':
325
- return hdShared.EDeviceType.Classic;
326
- case 'CLASSIC1S':
327
- return hdShared.EDeviceType.Classic1s;
328
- case 'MINI':
329
- return hdShared.EDeviceType.Mini;
330
- case 'TOUCH':
331
- return hdShared.EDeviceType.Touch;
332
- case 'PRO':
333
- return hdShared.EDeviceType.Pro;
334
- case 'PRO2':
335
- return hdShared.EDeviceType.Pro2;
336
- case 'PURE':
337
- return hdShared.EDeviceType.ClassicPure;
338
- }
339
- if (((_b = compatible.model) === null || _b === void 0 ? void 0 : _b.toString().toLowerCase()) === hdShared.EDeviceType.Pro2) {
340
- return hdShared.EDeviceType.Pro2;
341
- }
342
- const serialNo = resolveDeviceSerialNo(features);
343
- const prefix = serialNo.slice(0, 2).toLowerCase();
344
- if (prefix === 'bi' || prefix === 'cl')
345
- return hdShared.EDeviceType.Classic;
346
- if (prefix === 'cp')
347
- return hdShared.EDeviceType.ClassicPure;
348
- if (prefix === 'mi')
349
- return hdShared.EDeviceType.Mini;
350
- if (prefix === 'tc')
351
- return hdShared.EDeviceType.Touch;
352
- if (prefix === 'pr')
353
- return hdShared.EDeviceType.Pro;
354
- if (prefix === 'p2')
355
- return hdShared.EDeviceType.Pro2;
356
- const bootloaderMode = (_c = compatible.bootloaderMode) !== null && _c !== void 0 ? _c : compatible.bootloader_mode;
357
- if (!serialNo && bootloaderMode === true && compatible.model === '1') {
358
- return hdShared.EDeviceType.Classic;
359
- }
360
- return (_d = compatible.deviceType) !== null && _d !== void 0 ? _d : hdShared.EDeviceType.Unknown;
361
- };
362
- const resolveDeviceFirmwareType = (features) => {
363
- if (!features) {
364
- return hdShared.EFirmwareType.Universal;
365
- }
366
- const compatible = asCompatibleFeatures(features);
367
- if (compatible.firmwareType) {
368
- return compatible.firmwareType;
369
- }
370
- if (compatible.fw_vendor === 'OneKey Bitcoin-only') {
371
- return hdShared.EFirmwareType.BitcoinOnly;
372
- }
373
- const capabilities = compatible.capabilities;
374
- const supportsBitcoinLike = capabilities === null || capabilities === void 0 ? void 0 : capabilities.some(capability => capability === hdTransport.Enum_Capability.Capability_Bitcoin_like ||
375
- capability === 'Capability_Bitcoin_like');
376
- return (capabilities === null || capabilities === void 0 ? void 0 : capabilities.length) && !supportsBitcoinLike
377
- ? hdShared.EFirmwareType.BitcoinOnly
378
- : hdShared.EFirmwareType.Universal;
379
- };
380
- const resolveDeviceBleName = (features) => {
381
- var _a;
382
- if (!features)
383
- return null;
384
- const compatible = asCompatibleFeatures(features);
385
- return ((_a = firstNonEmptyString(compatible.bleName, compatible.onekey_ble_name, compatible.ble_name)) !== null && _a !== void 0 ? _a : null);
386
- };
387
- const resolveDeviceFirmwareVersion = (features) => {
388
- if (!features)
389
- return null;
390
- const compatible = asCompatibleFeatures(features);
391
- return firstMeaningfulVersion$1(compatible.firmwareVersion, compatible.onekey_firmware_version, compatible.onekey_version, versionFromParts(compatible.major_version, compatible.minor_version, compatible.patch_version));
392
- };
393
- const resolveDeviceBootloaderVersion = (features) => {
394
- var _a;
395
- if (!features)
396
- return null;
397
- const compatible = asCompatibleFeatures(features);
398
- const bootloaderMode = (_a = compatible.bootloaderMode) !== null && _a !== void 0 ? _a : compatible.bootloader_mode;
399
- return firstMeaningfulVersion$1(compatible.bootloaderVersion, compatible.onekey_boot_version, compatible.bootloader_version, compatible.onekey_bootloader_version, bootloaderMode
400
- ? versionFromParts(compatible.major_version, compatible.minor_version, compatible.patch_version)
401
- : null);
402
- };
403
- const resolveDeviceBoardVersion = (features) => {
404
- if (!features)
405
- return null;
406
- const compatible = asCompatibleFeatures(features);
407
- return firstMeaningfulVersion$1(compatible.boardVersion, compatible.onekey_board_version, compatible.boardloader_version, compatible.onekey_romloader_version, compatible.romloader_version);
408
- };
409
- const resolveDeviceBleFirmwareVersion = (features) => {
410
- if (!features)
411
- return null;
412
- const compatible = asCompatibleFeatures(features);
413
- return firstMeaningfulVersion$1(compatible.bleVersion, compatible.onekey_ble_version, compatible.ble_ver, compatible.onekey_coprocessor_version);
414
- };
415
-
416
- const getDeviceType = (features) => resolveDeviceType(features);
417
- const getDeviceTypeByBleName = (name) => {
418
- if (!name)
419
- return hdShared.EDeviceType.Unknown;
420
- if (/^BixinKey/i.test(name))
421
- return hdShared.EDeviceType.Classic;
422
- if (/^K/i.test(name))
423
- return hdShared.EDeviceType.Classic;
424
- if (/^T/i.test(name))
425
- return hdShared.EDeviceType.Touch;
426
- if (/^Touch/i.test(name))
427
- return hdShared.EDeviceType.Touch;
428
- if (/\bPro\s*2\b/i.test(name) || /^Pro2/i.test(name))
429
- return hdShared.EDeviceType.Pro2;
430
- if (/\bPro\b/i.test(name) || /^Pro/i.test(name))
431
- return hdShared.EDeviceType.Pro;
432
- return hdShared.EDeviceType.Unknown;
433
- };
434
- const getDeviceBleName = (features) => resolveDeviceBleName(features);
435
- const getDeviceSerialNo = (features) => resolveDeviceSerialNo(features);
436
- const getDeviceUUID = getDeviceSerialNo;
437
- const getDeviceLabel = (features) => {
438
- if (!features)
439
- return null;
440
- return 'label' in features && typeof features.label === 'string' && features.label.length > 0
441
- ? features.label
442
- : null;
443
- };
444
- const getMethodVersionRange = (features, getVersionRange) => {
445
- const deviceType = getDeviceType(features);
446
- const versionRange = getVersionRange(deviceType);
447
- if (versionRange) {
448
- return versionRange;
449
- }
450
- const modelFallbacks = [
451
- 'model_classic1s',
452
- 'model_classic',
453
- 'model_mini',
454
- 'model_touch',
455
- ];
456
- for (const model of modelFallbacks) {
457
- if (DeviceModelToTypes[model].includes(deviceType)) {
458
- const versionRange = getVersionRange(model);
459
- if (versionRange) {
460
- return versionRange;
461
- }
462
- }
463
- }
464
- return undefined;
465
- };
466
- const isMethodVersionRangeUnsupported = (versionRange) => (versionRange === null || versionRange === void 0 ? void 0 : versionRange.unsupported) === true;
467
- const getFirmwareType = (features) => resolveDeviceFirmwareType(features);
468
-
469
- const EMPTY_VERSION = [0, 0, 0];
470
- const parseDeviceVersion = (version) => {
471
- const parsed = version ? semver__default["default"].parse(version) : null;
472
- return parsed ? [parsed.major, parsed.minor, parsed.patch] : [...EMPTY_VERSION];
473
- };
474
- const getDeviceFirmwareVersion = (features) => parseDeviceVersion(resolveDeviceFirmwareVersion(features));
475
- const getDeviceBootloaderVersion = (features) => parseDeviceVersion(resolveDeviceBootloaderVersion(features));
476
- const getDeviceBoardloaderVersion = (features) => parseDeviceVersion(resolveDeviceBoardVersion(features));
477
- const getDeviceBLEFirmwareVersion = (features) => parseDeviceVersion(resolveDeviceBleFirmwareVersion(features));
478
-
479
- const PROTOCOL_V2_TARGETS = {
480
- BOOTLOADER: 'boot',
481
- APPLICATION_P1: 'app_v1',
482
- APPLICATION_P2: 'app_v2',
483
- COPROCESSOR: 'coprocessor',
484
- SE01: 'se01',
485
- SE02: 'se02',
486
- SE03: 'se03',
487
- SE04: 'se04',
488
- };
489
- const asRecord = (value) => value && typeof value === 'object' && !Array.isArray(value)
490
- ? value
491
- : undefined;
492
- const asRelease = (release) => asRecord(release === null || release === void 0 ? void 0 : release.release);
493
- const asString = (value) => typeof value === 'string' && value.length > 0 ? value : undefined;
494
- const asVersion = (value) => {
495
- if (!Array.isArray(value) ||
496
- value.length !== 3 ||
497
- value.some(part => typeof part !== 'number' || !Number.isSafeInteger(part) || part < 0)) {
498
- return undefined;
499
- }
500
- return value.join('.');
501
- };
502
- const asIntegrity = ({ size, sha256: value, }) => {
503
- const sha256Value = typeof value === 'string' && /^[a-f0-9]{64}$/iu.test(value) ? value.toLowerCase() : undefined;
504
- return Object.assign(Object.assign({}, (Number.isSafeInteger(size) && size > 0 ? { expectedSize: size } : {})), (sha256Value ? { expectedSha256: sha256Value } : {}));
505
- };
506
- const isUpgrade = (release) => (release === null || release === void 0 ? void 0 : release.status) === 'required' ||
507
- (release === null || release === void 0 ? void 0 : release.status) === 'outdated' ||
508
- (release === null || release === void 0 ? void 0 : release.shouldUpdate) === true;
509
- const assertArtifactUrl = (value, label) => {
510
- const raw = asString(value);
511
- if (!raw) {
512
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${label} has no downloadable artifact`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
513
- }
514
- const parsed = new URL(raw);
515
- if (parsed.protocol !== 'https:' ||
516
- parsed.port !== '' ||
517
- parsed.username ||
518
- parsed.password ||
519
- parsed.hash) {
520
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${label} URL is not canonical HTTPS`, {
521
- firmwareUpdateCode: 'FirmwarePlanInvalid',
522
- });
523
- }
524
- return raw;
525
- };
526
- const canonicalizeFirmwareUpdateContract = (value) => {
527
- if (Array.isArray(value)) {
528
- return value.map(canonicalizeFirmwareUpdateContract);
529
- }
530
- if (value && typeof value === 'object') {
531
- return Object.keys(value)
532
- .sort()
533
- .reduce((result, key) => {
534
- const item = value[key];
535
- if (item !== undefined) {
536
- result[key] = canonicalizeFirmwareUpdateContract(item);
537
- }
538
- return result;
539
- }, {});
540
- }
541
- return value;
542
- };
543
- const digestFirmwareUpdateContract = (value) => utils.bytesToHex(sha256.sha256(new TextEncoder().encode(JSON.stringify(canonicalizeFirmwareUpdateContract(value)))));
544
- const digestFirmwareUpdatePlan = (plan) => digestFirmwareUpdateContract(plan);
545
- const planError = (message) => {
546
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
547
- firmwareUpdateCode: 'FirmwarePlanInvalid',
548
- });
549
- };
550
- const assertExactKeys = (value, required, optional = []) => {
551
- const allowed = new Set([...required, ...optional]);
552
- if (required.some(key => !Object.prototype.hasOwnProperty.call(value, key)) ||
553
- Object.keys(value).some(key => !allowed.has(key))) {
554
- planError('Firmware update plan contains an invalid field set');
555
- }
556
- };
557
- const assertBoundedString = (value, label, maxLength = 256) => {
558
- if (typeof value !== 'string' || value.length === 0 || value.length > maxLength) {
559
- return planError(`Firmware update plan ${label} is invalid`);
560
- }
561
- return value;
562
- };
563
- const FIRMWARE_UPDATE_PLAN_TARGETS = new Set([
564
- 'firmware',
565
- 'ble',
566
- 'bootloader',
567
- 'resource',
568
- 'boot',
569
- 'app_v1',
570
- 'app_v2',
571
- 'coprocessor',
572
- 'se01',
573
- 'se02',
574
- 'se03',
575
- 'se04',
576
- ]);
577
- const FIRMWARE_UPDATE_PLAN_ROLES = new Set([
578
- 'firmware',
579
- 'ble',
580
- 'bootloader',
581
- 'resource',
582
- 'component',
583
- 'resourceBundle',
584
- ]);
585
- const PLAN_CONTAINERS = new Set(['raw', 'zip']);
586
- const PLAN_PLATFORMS = new Set([
587
- 'native',
588
- 'desktop',
589
- 'ext',
590
- 'web',
591
- 'web-embed',
592
- ]);
593
- const assertFirmwareUpdatePlan = (value) => {
594
- const plan = asRecord(value);
595
- if (!plan) {
596
- return planError('Firmware update plan must be an object');
597
- }
598
- assertExactKeys(plan, [
599
- 'schemaVersion',
600
- 'planDigest',
601
- 'executor',
602
- 'deviceIdentity',
603
- 'deviceModel',
604
- 'firmwareType',
605
- 'platform',
606
- 'artifacts',
607
- 'targetsToUpdate',
608
- ]);
609
- if (plan.schemaVersion !== 2 ||
610
- typeof plan.planDigest !== 'string' ||
611
- !/^[a-f0-9]{64}$/u.test(plan.planDigest) ||
612
- (plan.executor !== 'v2' && plan.executor !== 'v3' && plan.executor !== 'v4') ||
613
- !PLAN_PLATFORMS.has(plan.platform) ||
614
- (plan.firmwareType !== hdShared.EFirmwareType.Universal &&
615
- plan.firmwareType !== hdShared.EFirmwareType.BitcoinOnly)) {
616
- return planError('Firmware update plan header is invalid');
617
- }
618
- assertBoundedString(plan.deviceIdentity, 'device identity');
619
- assertBoundedString(plan.deviceModel, 'device model', 64);
620
- if (!Array.isArray(plan.artifacts) || plan.artifacts.length > 128) {
621
- return planError('Firmware update plan artifact set is invalid');
622
- }
623
- const artifactIds = new Set();
624
- const artifactTargets = new Set();
625
- for (const item of plan.artifacts) {
626
- const artifact = asRecord(item);
627
- if (!artifact) {
628
- return planError('Firmware update plan artifact is invalid');
629
- }
630
- assertExactKeys(artifact, ['artifactId', 'role', 'target', 'url', 'container'], ['logicalName', 'expectedSize', 'expectedSha256', 'targetVersion']);
631
- const artifactId = assertBoundedString(artifact.artifactId, 'artifact id', 160);
632
- if (artifactIds.has(artifactId)) {
633
- return planError('Firmware update plan contains duplicate artifact ids');
634
- }
635
- artifactIds.add(artifactId);
636
- if (!FIRMWARE_UPDATE_PLAN_ROLES.has(artifact.role) ||
637
- !FIRMWARE_UPDATE_PLAN_TARGETS.has(artifact.target) ||
638
- !PLAN_CONTAINERS.has(artifact.container)) {
639
- return planError('Firmware update plan artifact contract is invalid');
640
- }
641
- artifactTargets.add(artifact.target);
642
- assertArtifactUrl(artifact.url, `Firmware artifact ${artifactId}`);
643
- if (artifact.logicalName !== undefined) {
644
- assertBoundedString(artifact.logicalName, 'logical name', 256);
645
- }
646
- if (artifact.expectedSize !== undefined &&
647
- (!Number.isSafeInteger(artifact.expectedSize) || artifact.expectedSize <= 0)) {
648
- return planError('Firmware update plan artifact size is invalid');
649
- }
650
- if (artifact.expectedSha256 !== undefined &&
651
- (typeof artifact.expectedSha256 !== 'string' ||
652
- !/^[a-f0-9]{64}$/u.test(artifact.expectedSha256))) {
653
- return planError('Firmware update plan artifact digest is invalid');
654
- }
655
- if (artifact.targetVersion !== undefined) {
656
- assertBoundedString(artifact.targetVersion, 'target version', 64);
657
- }
658
- }
659
- if (!Array.isArray(plan.targetsToUpdate) ||
660
- plan.targetsToUpdate.some(target => !FIRMWARE_UPDATE_PLAN_TARGETS.has(target)) ||
661
- new Set(plan.targetsToUpdate).size !== plan.targetsToUpdate.length ||
662
- plan.targetsToUpdate.length !== artifactTargets.size ||
663
- plan.targetsToUpdate.some(target => !artifactTargets.has(target))) {
664
- return planError('Firmware update plan targets are invalid');
665
- }
666
- const legacyTargets = new Set([
667
- 'firmware',
668
- 'ble',
669
- 'bootloader',
670
- 'resource',
671
- ]);
672
- const legacyOnlyTargets = new Set(['firmware', 'ble', 'bootloader']);
673
- if (((plan.executor === 'v2' || plan.executor === 'v3') &&
674
- plan.targetsToUpdate.some(target => !legacyTargets.has(target))) ||
675
- (plan.executor === 'v4' &&
676
- plan.targetsToUpdate.some(target => legacyOnlyTargets.has(target))) ||
677
- (plan.artifacts.length > 0 &&
678
- (plan.platform === 'native' || plan.platform === 'desktop') &&
679
- plan.deviceIdentity === 'unavailable')) {
680
- return planError('Firmware update plan executor contract is invalid');
681
- }
682
- const _a = plan, { planDigest } = _a, withoutDigest = __rest(_a, ["planDigest"]);
683
- if (digestFirmwareUpdatePlan(withoutDigest) !== planDigest) {
684
- return planError('Firmware update plan digest is invalid');
685
- }
686
- return plan;
687
- };
688
- const selectResourceUrl = ({ release, features, platform, }) => {
689
- const resource = asString(release.resource);
690
- const fullResource = asString(release.fullResource);
691
- const range = release.fullResourceRange;
692
- const currentVersion = getDeviceFirmwareVersion(features).join('.');
693
- const targetVersion = asVersion(release.version);
694
- if (platform === 'desktop' &&
695
- fullResource &&
696
- targetVersion &&
697
- Array.isArray(range) &&
698
- range.length === 2 &&
699
- typeof range[0] === 'string' &&
700
- typeof range[1] === 'string' &&
701
- semver__default["default"].valid(currentVersion) &&
702
- semver__default["default"].valid(targetVersion) &&
703
- semver__default["default"].valid(range[0]) &&
704
- semver__default["default"].valid(range[1]) &&
705
- semver__default["default"].lt(currentVersion, range[0]) &&
706
- semver__default["default"].gte(targetVersion, range[1])) {
707
- return fullResource;
708
- }
709
- return resource;
710
- };
711
- const getExecutor = (features) => {
712
- const deviceType = getDeviceType(features);
713
- if (deviceType === hdShared.EDeviceType.Pro2) {
714
- return 'v4';
715
- }
716
- if (deviceType === hdShared.EDeviceType.Pro &&
717
- semver__default["default"].gte(getDeviceBootloaderVersion(features).join('.'), '2.8.0')) {
718
- return 'v3';
719
- }
720
- return 'v2';
721
- };
722
- const buildProtocolV2Artifacts = (release) => {
723
- var _a;
724
- const components = asRecord(release.components);
725
- if (!components) {
726
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 release has no component set', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
727
- }
728
- const installOrder = Array.isArray(release.installOrder)
729
- ? release.installOrder.filter((key) => typeof key === 'string')
730
- : [];
731
- const componentKeys = [
732
- ...installOrder,
733
- ...Object.keys(components).filter(key => !installOrder.includes(key)),
734
- ];
735
- const artifacts = [];
736
- const targets = [];
737
- const componentTargets = new Set();
738
- for (const key of componentKeys) {
739
- const component = asRecord(components[key]);
740
- const targetName = (_a = asString(component === null || component === void 0 ? void 0 : component.target)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
741
- if (targetName === 'ROMLOADER') {
742
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 ROMLOADER requires its dedicated loader flow', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
743
- }
744
- const target = targetName ? PROTOCOL_V2_TARGETS[targetName] : undefined;
745
- if (!component || !target) {
746
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} has an unsupported target`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
747
- }
748
- if (componentTargets.has(target)) {
749
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} duplicates target ${target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
750
- }
751
- componentTargets.add(target);
752
- artifacts.push(Object.assign(Object.assign({ artifactId: `component:${target}`, role: 'component', target, url: assertArtifactUrl(component.url, `Protocol V2 component ${key}`), container: 'raw', logicalName: key }, asIntegrity({
753
- size: component.expectedSize,
754
- sha256: component.fingerprint,
755
- })), (asVersion(component.version) ? { targetVersion: asVersion(component.version) } : {})));
756
- targets.push(target);
757
- }
758
- const bundles = Array.isArray(release.resourceBundles) ? release.resourceBundles : [];
759
- const resourceBundleNames = new Set();
760
- for (const value of bundles) {
761
- const bundle = asRecord(value);
762
- const name = asString(bundle === null || bundle === void 0 ? void 0 : bundle.name);
763
- if (!bundle || !name) {
764
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource bundle is invalid', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
765
- }
766
- if (resourceBundleNames.has(name)) {
767
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource bundle duplicates name ${name}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
768
- }
769
- resourceBundleNames.add(name);
770
- artifacts.push(Object.assign({ artifactId: `resourceBundle:${name}`, role: 'resourceBundle', target: 'resource', url: assertArtifactUrl(bundle.url, `Protocol V2 resource bundle ${name}`), container: 'raw', logicalName: name }, asIntegrity({
771
- size: bundle.expectedSize,
772
- sha256: bundle.fingerprint,
773
- })));
774
- }
775
- if (bundles.length > 0) {
776
- targets.push('resource');
777
- }
778
- return { artifacts, targets: [...new Set(targets)] };
779
- };
780
- const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, ble, bootloader, }) => {
781
- var _a, _b, _c, _d, _e, _f, _g;
782
- const executor = getExecutor(features);
783
- let artifacts = [];
784
- let targetsToUpdate = [];
785
- const firmwareRelease = asRelease(firmware);
786
- if (executor === 'v4' && isUpgrade(firmware)) {
787
- const protocolV2 = buildProtocolV2Artifacts(firmwareRelease !== null && firmwareRelease !== void 0 ? firmwareRelease : {});
788
- artifacts = protocolV2.artifacts;
789
- targetsToUpdate = protocolV2.targets;
790
- }
791
- else {
792
- if (isUpgrade(bootloader)) {
793
- artifacts.push(Object.assign(Object.assign({ artifactId: 'bootloader', role: 'bootloader', target: 'bootloader', url: assertArtifactUrl((_a = asRelease(bootloader)) === null || _a === void 0 ? void 0 : _a.bootloaderResource, 'Bootloader release'), container: 'raw' }, asIntegrity({
794
- size: (_b = asRelease(bootloader)) === null || _b === void 0 ? void 0 : _b.bootloaderExpectedSize,
795
- sha256: (_c = asRelease(bootloader)) === null || _c === void 0 ? void 0 : _c.bootloaderFingerprint,
796
- })), (asVersion((_d = asRelease(bootloader)) === null || _d === void 0 ? void 0 : _d.bootloaderVersion)
797
- ? {
798
- targetVersion: asVersion((_e = asRelease(bootloader)) === null || _e === void 0 ? void 0 : _e.bootloaderVersion),
799
- }
800
- : {})));
801
- }
802
- if (isUpgrade(firmware)) {
803
- if (!firmwareRelease) {
804
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware release is invalid', {
805
- firmwareUpdateCode: 'FirmwarePlanInvalid',
806
- });
807
- }
808
- artifacts.push(Object.assign(Object.assign({ artifactId: 'firmware', role: 'firmware', target: 'firmware', url: assertArtifactUrl(firmwareRelease.url, 'Firmware release'), container: 'raw' }, asIntegrity({
809
- size: firmwareRelease.expectedSize,
810
- sha256: firmwareRelease.fingerprint,
811
- })), (asVersion(firmwareRelease.version)
812
- ? { targetVersion: asVersion(firmwareRelease.version) }
813
- : {})));
814
- const resourceUrl = selectResourceUrl({
815
- release: firmwareRelease,
816
- features,
817
- platform,
818
- });
819
- if (resourceUrl) {
820
- artifacts.push(Object.assign({ artifactId: 'resource', role: 'resource', target: 'resource', url: assertArtifactUrl(resourceUrl, 'Firmware resource release'), container: 'zip' }, asIntegrity({
821
- size: resourceUrl === asString(firmwareRelease.fullResource)
822
- ? firmwareRelease.fullResourceExpectedSize
823
- : firmwareRelease.resourceExpectedSize,
824
- sha256: resourceUrl === asString(firmwareRelease.fullResource)
825
- ? firmwareRelease.fullResourceFingerprint
826
- : firmwareRelease.resourceFingerprint,
827
- })));
828
- }
829
- }
830
- if (isUpgrade(ble)) {
831
- const bleRelease = asRelease(ble);
832
- artifacts.push(Object.assign(Object.assign({ artifactId: 'ble', role: 'ble', target: 'ble', url: assertArtifactUrl((_f = bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.webUpdate) !== null && _f !== void 0 ? _f : bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.url, 'BLE release'), container: 'raw' }, asIntegrity({
833
- size: bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.expectedSize,
834
- sha256: (_g = bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.fingerprintWeb) !== null && _g !== void 0 ? _g : bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.fingerprint,
835
- })), (asVersion(bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.version)
836
- ? { targetVersion: asVersion(bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.version) }
837
- : {})));
838
- }
839
- targetsToUpdate = [...new Set(artifacts.map(artifact => artifact.target))];
840
- }
841
- const deviceIdentity = getDeviceUUID(features);
842
- if (artifacts.length > 0 &&
843
- (platform === 'native' || platform === 'desktop') &&
844
- !deviceIdentity) {
845
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Prepared firmware update requires a stable device identity', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
846
- }
847
- const planWithoutDigest = {
848
- schemaVersion: 2,
849
- executor,
850
- deviceIdentity: deviceIdentity || 'unavailable',
851
- deviceModel: String(getDeviceType(features)),
852
- firmwareType,
853
- platform,
854
- artifacts,
855
- targetsToUpdate,
856
- };
857
- return Object.assign(Object.assign({}, planWithoutDigest), { planDigest: digestFirmwareUpdatePlan(planWithoutDigest) });
858
- };
859
-
860
- const preparedPlanError = (message) => {
861
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
862
- firmwareUpdateCode: 'FirmwarePreparedPlanInvalid',
863
- });
864
- };
865
- const digestPreparedPlan = (plan) => digestFirmwareUpdateContract(plan);
866
- const assertOpaqueLeaseRef = (value) => {
867
- if (typeof value !== 'string' ||
868
- value.length === 0 ||
869
- value.length > 160 ||
870
- value.includes('/') ||
871
- value.includes('\\')) {
872
- return preparedPlanError('Firmware prepared plan leaseRef must be opaque');
873
- }
874
- return value;
875
- };
876
- const getFirmwareUpdateResourceName = (value) => {
877
- const normalized = typeof value === 'string' ? value.normalize('NFC') : undefined;
878
- const parts = normalized === null || normalized === void 0 ? void 0 : normalized.split('/');
879
- const resourceName = parts === null || parts === void 0 ? void 0 : parts.at(-1);
880
- if (typeof value !== 'string' ||
881
- value.length === 0 ||
882
- value.length > 512 ||
883
- value !== normalized ||
884
- value.startsWith('/') ||
885
- value.includes('\\') ||
886
- value.includes(':') ||
887
- [...value].some(char => {
888
- const code = char.charCodeAt(0);
889
- return code <= 0x1f || code === 0x7f;
890
- }) ||
891
- !(parts === null || parts === void 0 ? void 0 : parts.every(part => part.length > 0 &&
892
- part !== '.' &&
893
- part !== '..' &&
894
- !part.endsWith('.') &&
895
- !part.endsWith(' '))) ||
896
- !resourceName ||
897
- resourceName.length > 128) {
898
- return preparedPlanError('Firmware prepared plan entry name is invalid');
899
- }
900
- return resourceName;
901
- };
902
- const assertPreparedEntry = (value) => {
903
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
904
- return preparedPlanError('Firmware prepared plan entry must be an object');
905
- }
906
- const entry = value;
907
- if (Object.keys(entry).length !== 2 ||
908
- !Object.prototype.hasOwnProperty.call(entry, 'entryName') ||
909
- !Object.prototype.hasOwnProperty.call(entry, 'artifact')) {
910
- return preparedPlanError('Firmware prepared plan entry fields are invalid');
911
- }
912
- getFirmwareUpdateResourceName(entry.entryName);
913
- assertFirmwareArtifactReference(entry.artifact);
914
- return value;
915
- };
916
- const assertPreparedArtifacts = ({ plan, artifacts, }) => {
917
- if (artifacts.length !== plan.artifacts.length) {
918
- return preparedPlanError('Firmware prepared plan does not cover every artifact');
919
- }
920
- const inputs = new Map();
921
- for (const input of artifacts) {
922
- if (!input ||
923
- typeof input !== 'object' ||
924
- typeof input.artifactId !== 'string' ||
925
- inputs.has(input.artifactId)) {
926
- return preparedPlanError('Firmware prepared plan contains a duplicate artifact receipt');
927
- }
928
- inputs.set(input.artifactId, input);
929
- }
930
- return plan.artifacts.map(planArtifact => {
931
- var _a;
932
- const input = inputs.get(planArtifact.artifactId);
933
- if (!input) {
934
- return preparedPlanError('Firmware prepared plan artifact receipt is missing');
935
- }
936
- const artifact = assertFirmwareArtifactReference(input.artifact);
937
- if ((planArtifact.expectedSize !== undefined && artifact.size !== planArtifact.expectedSize) ||
938
- (planArtifact.expectedSha256 !== undefined &&
939
- artifact.sha256.toLowerCase() !== planArtifact.expectedSha256.toLowerCase())) {
940
- return preparedPlanError('Firmware prepared plan receipt does not match the update plan');
941
- }
942
- const materializedEntries = (_a = input.materializedEntries) === null || _a === void 0 ? void 0 : _a.map(value => {
943
- const entry = assertPreparedEntry(value);
944
- return {
945
- entryName: entry.entryName,
946
- artifact: Object.assign(Object.assign({}, entry.artifact), { sha256: entry.artifact.sha256.toLowerCase() }),
947
- };
948
- });
949
- if ((planArtifact.container === 'raw' && (materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length)) ||
950
- (planArtifact.container === 'zip' && !(materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length))) {
951
- return preparedPlanError('Firmware prepared plan materialization is incomplete');
952
- }
953
- if (materializedEntries &&
954
- new Set(materializedEntries.map(entry => getFirmwareUpdateResourceName(entry.entryName).toLowerCase())).size !== materializedEntries.length) {
955
- return preparedPlanError('Firmware prepared plan contains duplicate entry names');
956
- }
957
- return Object.assign(Object.assign(Object.assign(Object.assign({ artifactId: planArtifact.artifactId, role: planArtifact.role, target: planArtifact.target, container: planArtifact.container }, (planArtifact.logicalName ? { logicalName: planArtifact.logicalName } : {})), (planArtifact.targetVersion ? { targetVersion: planArtifact.targetVersion } : {})), { artifact: Object.assign(Object.assign({}, artifact), { sha256: artifact.sha256.toLowerCase() }) }), ((materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length) ? { materializedEntries } : {}));
958
- });
959
- };
960
- const prepareFirmwareUpdatePlan = ({ plan: value, leaseRef, artifacts, }) => {
961
- const plan = assertFirmwareUpdatePlan(value);
962
- const planWithoutDigest = {
963
- schemaVersion: 2,
964
- planDigest: plan.planDigest,
965
- networkPolicy: 'forbid',
966
- executor: plan.executor,
967
- deviceIdentity: plan.deviceIdentity,
968
- deviceModel: plan.deviceModel,
969
- firmwareType: plan.firmwareType,
970
- platform: plan.platform,
971
- leaseRef: assertOpaqueLeaseRef(leaseRef),
972
- artifacts: assertPreparedArtifacts({ plan, artifacts }),
973
- targetsToUpdate: plan.targetsToUpdate,
974
- };
975
- return Object.assign(Object.assign({}, planWithoutDigest), { preparedPlanDigest: digestPreparedPlan(planWithoutDigest) });
976
- };
977
- const validateFirmwareUpdatePreparedPlan = (value) => {
978
- var _a, _b, _c;
979
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
980
- return preparedPlanError('Firmware prepared plan must be an object');
981
- }
982
- const preparedPlan = value;
983
- const exactKeys = [
984
- 'schemaVersion',
985
- 'preparedPlanDigest',
986
- 'planDigest',
987
- 'networkPolicy',
988
- 'executor',
989
- 'deviceIdentity',
990
- 'deviceModel',
991
- 'firmwareType',
992
- 'platform',
993
- 'leaseRef',
994
- 'artifacts',
995
- 'targetsToUpdate',
996
- ];
997
- if (Object.keys(value).length !== exactKeys.length ||
998
- exactKeys.some(key => !Object.prototype.hasOwnProperty.call(value, key)) ||
999
- preparedPlan.schemaVersion !== 2 ||
1000
- preparedPlan.networkPolicy !== 'forbid' ||
1001
- !/^[a-f0-9]{64}$/u.test(preparedPlan.planDigest) ||
1002
- !/^[a-f0-9]{64}$/u.test(preparedPlan.preparedPlanDigest) ||
1003
- !Array.isArray(preparedPlan.artifacts) ||
1004
- !Array.isArray(preparedPlan.targetsToUpdate) ||
1005
- (preparedPlan.executor !== 'v2' &&
1006
- preparedPlan.executor !== 'v3' &&
1007
- preparedPlan.executor !== 'v4') ||
1008
- (preparedPlan.platform !== 'native' &&
1009
- preparedPlan.platform !== 'desktop' &&
1010
- preparedPlan.platform !== 'ext' &&
1011
- preparedPlan.platform !== 'web' &&
1012
- preparedPlan.platform !== 'web-embed') ||
1013
- (preparedPlan.firmwareType !== 'universal' && preparedPlan.firmwareType !== 'bitcoinonly') ||
1014
- typeof preparedPlan.deviceIdentity !== 'string' ||
1015
- preparedPlan.deviceIdentity.length === 0 ||
1016
- typeof preparedPlan.deviceModel !== 'string' ||
1017
- preparedPlan.deviceModel.length === 0) {
1018
- return preparedPlanError('Firmware prepared plan header is invalid');
1019
- }
1020
- assertOpaqueLeaseRef(preparedPlan.leaseRef);
1021
- const artifactIds = new Set();
1022
- const artifactTargets = new Set();
1023
- for (const artifact of preparedPlan.artifacts) {
1024
- if (!artifact || typeof artifact !== 'object') {
1025
- return preparedPlanError('Firmware prepared plan artifact is invalid');
1026
- }
1027
- const artifactKeys = [
1028
- 'artifactId',
1029
- 'role',
1030
- 'target',
1031
- 'container',
1032
- 'artifact',
1033
- ...(artifact.logicalName !== undefined ? ['logicalName'] : []),
1034
- ...(artifact.targetVersion !== undefined ? ['targetVersion'] : []),
1035
- ...(artifact.materializedEntries !== undefined ? ['materializedEntries'] : []),
1036
- ];
1037
- if (typeof artifact.artifactId !== 'string' ||
1038
- artifact.artifactId.length === 0 ||
1039
- artifactIds.has(artifact.artifactId) ||
1040
- Object.keys(artifact).length !== artifactKeys.length ||
1041
- artifactKeys.some(key => !Object.prototype.hasOwnProperty.call(artifact, key)) ||
1042
- !FIRMWARE_UPDATE_PLAN_ROLES.has(artifact.role) ||
1043
- !FIRMWARE_UPDATE_PLAN_TARGETS.has(artifact.target) ||
1044
- (artifact.container !== 'raw' && artifact.container !== 'zip') ||
1045
- (artifact.logicalName !== undefined &&
1046
- (typeof artifact.logicalName !== 'string' || artifact.logicalName.length === 0)) ||
1047
- (artifact.targetVersion !== undefined &&
1048
- (typeof artifact.targetVersion !== 'string' || artifact.targetVersion.length === 0)) ||
1049
- (artifact.materializedEntries !== undefined &&
1050
- !Array.isArray(artifact.materializedEntries)) ||
1051
- (artifact.container === 'raw' && Boolean((_a = artifact.materializedEntries) === null || _a === void 0 ? void 0 : _a.length)) ||
1052
- (artifact.container === 'zip' && !((_b = artifact.materializedEntries) === null || _b === void 0 ? void 0 : _b.length))) {
1053
- return preparedPlanError('Firmware prepared plan artifact is invalid');
1054
- }
1055
- artifactIds.add(artifact.artifactId);
1056
- artifactTargets.add(artifact.target);
1057
- assertFirmwareArtifactReference(artifact.artifact);
1058
- (_c = artifact.materializedEntries) === null || _c === void 0 ? void 0 : _c.forEach(assertPreparedEntry);
1059
- }
1060
- if (preparedPlan.targetsToUpdate.some(target => !FIRMWARE_UPDATE_PLAN_TARGETS.has(target)) ||
1061
- new Set(preparedPlan.targetsToUpdate).size !== preparedPlan.targetsToUpdate.length ||
1062
- preparedPlan.targetsToUpdate.length !== artifactTargets.size ||
1063
- preparedPlan.targetsToUpdate.some(target => !artifactTargets.has(target))) {
1064
- return preparedPlanError('Firmware prepared plan targets are invalid');
1065
- }
1066
- const { preparedPlanDigest } = preparedPlan, withoutDigest = __rest(preparedPlan, ["preparedPlanDigest"]);
1067
- if (digestPreparedPlan(withoutDigest) !== preparedPlanDigest) {
1068
- return preparedPlanError('Firmware prepared plan digest is invalid');
1069
- }
1070
- return preparedPlan;
1071
- };
1072
- const assertFirmwareUpdatePreparedPlanDeviceIdentity = ({ preparedPlan: value, deviceIdentity, }) => {
1073
- const preparedPlan = validateFirmwareUpdatePreparedPlan(value);
1074
- if (!deviceIdentity || preparedPlan.deviceIdentity !== deviceIdentity) {
1075
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckDeviceIdError);
1076
- }
1077
- return preparedPlan;
1078
- };
1079
- const sameArtifactReference = (first, second) => first.artifactRef === second.artifactRef &&
1080
- first.size === second.size &&
1081
- first.sha256.toLowerCase() === second.sha256.toLowerCase();
1082
- const assertFirmwareUpdatePreparedPlanBinding = ({ preparedPlan: value, executor, platform, deviceIdentity, scopeTargets, bindings, }) => {
1083
- var _a;
1084
- const preparedPlan = validateFirmwareUpdatePreparedPlan(value);
1085
- if (preparedPlan.executor !== executor ||
1086
- (platform !== undefined && preparedPlan.platform !== platform) ||
1087
- (deviceIdentity !== undefined && preparedPlan.deviceIdentity !== deviceIdentity)) {
1088
- return preparedPlanError('Firmware prepared plan executor binding is invalid');
1089
- }
1090
- const scope = new Set(scopeTargets);
1091
- const expectedBindings = [];
1092
- for (const artifact of preparedPlan.artifacts) {
1093
- if (scope.has(artifact.target)) {
1094
- if (artifact.container === 'zip') {
1095
- for (const entry of (_a = artifact.materializedEntries) !== null && _a !== void 0 ? _a : []) {
1096
- expectedBindings.push(Object.assign(Object.assign({ target: artifact.target }, (artifact.target === 'resource' && artifact.logicalName
1097
- ? { logicalName: artifact.logicalName }
1098
- : {})), { entryName: entry.entryName, artifact: entry.artifact }));
1099
- }
1100
- }
1101
- else {
1102
- expectedBindings.push(Object.assign(Object.assign({ target: artifact.target }, (artifact.target === 'resource' && artifact.logicalName
1103
- ? { logicalName: artifact.logicalName }
1104
- : {})), { artifact: artifact.artifact }));
1105
- }
1106
- }
1107
- }
1108
- if (expectedBindings.length !== bindings.length ||
1109
- expectedBindings.some(expected => {
1110
- const matching = bindings.filter(binding => binding.target === expected.target &&
1111
- binding.logicalName === expected.logicalName &&
1112
- binding.entryName === expected.entryName &&
1113
- sameArtifactReference(binding.artifact, expected.artifact));
1114
- return matching.length !== 1;
1115
- })) {
1116
- return preparedPlanError('Firmware prepared plan artifact binding is invalid');
1117
- }
1118
- return preparedPlan;
1119
- };
1120
-
1121
- const bindingError = (message) => {
1122
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
1123
- firmwareUpdateCode: 'FirmwareArtifactReaderInvalid',
1124
- });
1125
- };
1126
- class FirmwareHostBindingRegistry {
1127
- constructor() {
1128
- this.generation = 0;
1129
- }
1130
- register(binding) {
1131
- var _a;
1132
- if (!binding ||
1133
- typeof ((_a = binding.artifactReader) === null || _a === void 0 ? void 0 : _a.open) !== 'function' ||
1134
- typeof binding.artifactReader.read !== 'function' ||
1135
- typeof binding.artifactReader.close !== 'function') {
1136
- return bindingError('Firmware host binding is invalid');
1137
- }
1138
- this.generation += 1;
1139
- this.binding = binding;
1140
- return this.generation;
1141
- }
1142
- unregister(generation) {
1143
- if (generation !== undefined && generation !== this.generation) {
1144
- return false;
1145
- }
1146
- this.generation += 1;
1147
- this.binding = undefined;
1148
- return true;
1149
- }
1150
- getGeneration() {
1151
- return this.generation;
1152
- }
1153
- resolve(generation) {
1154
- if (!Number.isSafeInteger(generation) ||
1155
- generation <= 0 ||
1156
- generation !== this.generation ||
1157
- !this.binding) {
1158
- return bindingError(`Firmware host binding generation ${generation} is stale`);
1159
- }
1160
- const { binding } = this;
1161
- const assertCurrent = () => {
1162
- if (generation !== this.generation || binding !== this.binding) {
1163
- bindingError(`Firmware host binding generation ${generation} is stale`);
1164
- }
1165
- };
1166
- return {
1167
- artifactReader: {
1168
- open: (input) => __awaiter(this, void 0, void 0, function* () {
1169
- assertCurrent();
1170
- const opened = yield binding.artifactReader.open(input);
1171
- try {
1172
- assertCurrent();
1173
- }
1174
- catch (error) {
1175
- if (opened === null || opened === void 0 ? void 0 : opened.readerId) {
1176
- yield binding.artifactReader
1177
- .close({ readerId: opened.readerId })
1178
- .catch(() => undefined);
1179
- }
1180
- throw error;
1181
- }
1182
- return opened;
1183
- }),
1184
- read: (input) => __awaiter(this, void 0, void 0, function* () {
1185
- assertCurrent();
1186
- const result = yield binding.artifactReader.read(input);
1187
- assertCurrent();
1188
- return result;
1189
- }),
1190
- close: input => binding.artifactReader.close(input),
1191
- },
1192
- };
1193
- }
1194
- }
1195
- const firmwareHostBindingRegistry = new FirmwareHostBindingRegistry();
1196
- const registerFirmwareUpdateHostBinding = (binding) => firmwareHostBindingRegistry.register(binding);
1197
- const unregisterFirmwareUpdateHostBinding = (generation) => firmwareHostBindingRegistry.unregister(generation);
1198
- const getFirmwareUpdateHostBindingGeneration = () => firmwareHostBindingRegistry.getGeneration();
1199
- const resolveFirmwareUpdateHostBinding = (generation) => firmwareHostBindingRegistry.resolve(generation !== null && generation !== void 0 ? generation : Number.NaN);
1200
-
1201
90
  const callbackManager = new Map();
1202
91
  const generateCallbackId = () => `callback_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
1203
92
  const registerCallback = (id, callback) => {
@@ -1220,22 +109,15 @@ const inject = ({ call, cancel, dispose, eventEmitter, init, updateSettings, swi
1220
109
  }, removeAllListeners: type => {
1221
110
  eventEmitter.removeAllListeners(type);
1222
111
  }, init,
1223
- call, dispose: () => __awaiter(void 0, void 0, void 0, function* () {
1224
- unregisterFirmwareUpdateHostBinding();
1225
- yield dispose();
1226
- }), uiResponse,
112
+ call,
113
+ dispose,
114
+ uiResponse,
1227
115
  cancel,
1228
116
  updateSettings,
1229
117
  switchTransport }, createCoreApi(call));
1230
118
  return api;
1231
119
  };
1232
120
  const createCoreApi = (call) => ({
1233
- getFirmwareUpdateCapabilities,
1234
- registerFirmwareUpdateHostBinding,
1235
- unregisterFirmwareUpdateHostBinding,
1236
- getFirmwareUpdateHostBindingGeneration,
1237
- prepareFirmwareUpdatePlan,
1238
- validateFirmwareUpdatePreparedPlan,
1239
121
  getLogs: () => call({ method: 'getLogs' }),
1240
122
  clearSessionCache: params => call(Object.assign(Object.assign({}, params), { method: 'clearSessionCache' })),
1241
123
  searchDevices: params => call(Object.assign(Object.assign({}, params), { method: 'searchDevices' })),
@@ -1254,6 +136,7 @@ const createCoreApi = (call) => ({
1254
136
  checkFirmwareTypeAvailable: params => call(Object.assign(Object.assign({}, params), { method: 'checkFirmwareTypeAvailable' })),
1255
137
  cipherKeyValue: (connectId, deviceId, params) => call(Object.assign(Object.assign({}, params), { connectId, deviceId, method: 'cipherKeyValue' })),
1256
138
  testInitializeDeviceDuration: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'testInitializeDeviceDuration' })),
139
+ testProtocolV2Ping: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'testProtocolV2Ping' })),
1257
140
  preInitialize: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'preInitialize' })),
1258
141
  deviceBackup: connectId => call({ connectId, method: 'deviceBackup' }),
1259
142
  deviceChangePin: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceChangePin' })),
@@ -1396,10 +279,9 @@ const lowLevelInject = ({ call, cancel, dispose, eventEmitter, init, uiResponse,
1396
279
  const api = Object.assign({ addHardwareGlobalEventListener, removeAllListeners: type => {
1397
280
  eventEmitter.removeAllListeners(type);
1398
281
  }, init,
1399
- call, dispose: () => __awaiter(void 0, void 0, void 0, function* () {
1400
- unregisterFirmwareUpdateHostBinding();
1401
- yield dispose();
1402
- }), uiResponse,
282
+ call,
283
+ dispose,
284
+ uiResponse,
1403
285
  cancel,
1404
286
  updateSettings,
1405
287
  switchTransport, emit: () => { } }, createCoreApi(call));
@@ -1903,10 +785,7 @@ const topLevelInject = () => {
1903
785
  }, call }, createCoreApi(call)), { removeAllListeners: type => {
1904
786
  eventEmitter.removeAllListeners(type);
1905
787
  lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.removeAllListeners(type);
1906
- }, dispose: () => __awaiter(void 0, void 0, void 0, function* () {
1907
- unregisterFirmwareUpdateHostBinding();
1908
- yield (lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.dispose());
1909
- }), uiResponse: response => lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.uiResponse(response), cancel: (connectId) => lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.cancel(connectId), updateSettings: settings => { var _a; return (_a = lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.updateSettings(settings)) !== null && _a !== void 0 ? _a : Promise.resolve(false); }, switchTransport: (env) => { var _a; return (_a = lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.switchTransport(env)) !== null && _a !== void 0 ? _a : Promise.resolve({ success: false }); } });
788
+ }, dispose: () => lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.dispose(), uiResponse: response => lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.uiResponse(response), cancel: (connectId) => lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.cancel(connectId), updateSettings: settings => { var _a; return (_a = lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.updateSettings(settings)) !== null && _a !== void 0 ? _a : Promise.resolve(false); }, switchTransport: (env) => { var _a; return (_a = lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.switchTransport(env)) !== null && _a !== void 0 ? _a : Promise.resolve({ success: false }); } });
1910
789
  return api;
1911
790
  };
1912
791
 
@@ -2474,6 +1353,221 @@ function cleanupSdkInstance(sdkInstanceId) {
2474
1353
  }
2475
1354
  }
2476
1355
 
1356
+ exports.EOneKeyDeviceMode = void 0;
1357
+ (function (EOneKeyDeviceMode) {
1358
+ EOneKeyDeviceMode["bootloader"] = "bootloader";
1359
+ EOneKeyDeviceMode["normal"] = "normal";
1360
+ EOneKeyDeviceMode["notInitialized"] = "notInitialized";
1361
+ EOneKeyDeviceMode["backupMode"] = "backupMode";
1362
+ })(exports.EOneKeyDeviceMode || (exports.EOneKeyDeviceMode = {}));
1363
+ const DeviceModelToTypes = {
1364
+ model_mini: [
1365
+ hdShared.EDeviceType.Classic,
1366
+ hdShared.EDeviceType.Classic1s,
1367
+ hdShared.EDeviceType.ClassicPure,
1368
+ hdShared.EDeviceType.Mini,
1369
+ ],
1370
+ model_touch: [hdShared.EDeviceType.Touch, hdShared.EDeviceType.Pro],
1371
+ model_classic: [hdShared.EDeviceType.Classic, hdShared.EDeviceType.Classic1s, hdShared.EDeviceType.ClassicPure],
1372
+ model_classic1s: [hdShared.EDeviceType.Classic1s, hdShared.EDeviceType.ClassicPure],
1373
+ };
1374
+ const DeviceTypeToModels = {
1375
+ [hdShared.EDeviceType.Classic]: ['model_classic', 'model_mini'],
1376
+ [hdShared.EDeviceType.Classic1s]: ['model_classic', 'model_mini', 'model_classic1s'],
1377
+ [hdShared.EDeviceType.ClassicPure]: ['model_classic', 'model_mini', 'model_classic1s'],
1378
+ [hdShared.EDeviceType.Mini]: ['model_mini'],
1379
+ [hdShared.EDeviceType.Touch]: ['model_touch'],
1380
+ [hdShared.EDeviceType.Pro]: ['model_touch'],
1381
+ [hdShared.EDeviceType.Pro2]: [],
1382
+ [hdShared.EDeviceType.Unknown]: [],
1383
+ };
1384
+
1385
+ const asCompatibleFeatures = (features) => features;
1386
+ const firstNonEmptyString = (...values) => values.find(value => typeof value === 'string' && value.length > 0);
1387
+ const firstMeaningfulVersion$1 = (...versions) => { var _a; return (_a = versions.find(version => Boolean(version && version !== '0.0.0'))) !== null && _a !== void 0 ? _a : null; };
1388
+ const versionFromParts = (major, minor, patch) => [major, minor, patch].map(part => Number(part) || 0).join('.');
1389
+ const resolveDeviceSerialNo = (features) => {
1390
+ var _a;
1391
+ if (!features)
1392
+ return '';
1393
+ const compatible = asCompatibleFeatures(features);
1394
+ return ((_a = firstNonEmptyString(compatible.serialNo, compatible.onekey_serial_no, compatible.onekey_serial, compatible.serial_no)) !== null && _a !== void 0 ? _a : '');
1395
+ };
1396
+ const resolveDeviceType = (features) => {
1397
+ var _a, _b, _c, _d;
1398
+ if (!features || typeof features !== 'object') {
1399
+ return hdShared.EDeviceType.Unknown;
1400
+ }
1401
+ const compatible = asCompatibleFeatures(features);
1402
+ if (compatible.deviceType && compatible.deviceType !== hdShared.EDeviceType.Unknown) {
1403
+ return compatible.deviceType;
1404
+ }
1405
+ switch ((_a = compatible.onekey_device_type) === null || _a === void 0 ? void 0 : _a.toString().toUpperCase()) {
1406
+ case 'CLASSIC':
1407
+ return hdShared.EDeviceType.Classic;
1408
+ case 'CLASSIC1S':
1409
+ return hdShared.EDeviceType.Classic1s;
1410
+ case 'MINI':
1411
+ return hdShared.EDeviceType.Mini;
1412
+ case 'TOUCH':
1413
+ return hdShared.EDeviceType.Touch;
1414
+ case 'PRO':
1415
+ return hdShared.EDeviceType.Pro;
1416
+ case 'PRO2':
1417
+ return hdShared.EDeviceType.Pro2;
1418
+ case 'PURE':
1419
+ return hdShared.EDeviceType.ClassicPure;
1420
+ }
1421
+ if (((_b = compatible.model) === null || _b === void 0 ? void 0 : _b.toString().toLowerCase()) === hdShared.EDeviceType.Pro2) {
1422
+ return hdShared.EDeviceType.Pro2;
1423
+ }
1424
+ const serialNo = resolveDeviceSerialNo(features);
1425
+ const prefix = serialNo.slice(0, 2).toLowerCase();
1426
+ if (prefix === 'bi' || prefix === 'cl')
1427
+ return hdShared.EDeviceType.Classic;
1428
+ if (prefix === 'cp')
1429
+ return hdShared.EDeviceType.ClassicPure;
1430
+ if (prefix === 'mi')
1431
+ return hdShared.EDeviceType.Mini;
1432
+ if (prefix === 'tc')
1433
+ return hdShared.EDeviceType.Touch;
1434
+ if (prefix === 'pr')
1435
+ return hdShared.EDeviceType.Pro;
1436
+ if (prefix === 'p2')
1437
+ return hdShared.EDeviceType.Pro2;
1438
+ const bootloaderMode = (_c = compatible.bootloaderMode) !== null && _c !== void 0 ? _c : compatible.bootloader_mode;
1439
+ if (!serialNo && bootloaderMode === true && compatible.model === '1') {
1440
+ return hdShared.EDeviceType.Classic;
1441
+ }
1442
+ return (_d = compatible.deviceType) !== null && _d !== void 0 ? _d : hdShared.EDeviceType.Unknown;
1443
+ };
1444
+ const resolveDeviceFirmwareType = (features) => {
1445
+ if (!features) {
1446
+ return hdShared.EFirmwareType.Universal;
1447
+ }
1448
+ const compatible = asCompatibleFeatures(features);
1449
+ if (compatible.firmwareType) {
1450
+ return compatible.firmwareType;
1451
+ }
1452
+ if (compatible.fw_vendor === 'OneKey Bitcoin-only') {
1453
+ return hdShared.EFirmwareType.BitcoinOnly;
1454
+ }
1455
+ const capabilities = compatible.capabilities;
1456
+ const supportsBitcoinLike = capabilities === null || capabilities === void 0 ? void 0 : capabilities.some(capability => capability === hdTransport.Enum_Capability.Capability_Bitcoin_like ||
1457
+ capability === 'Capability_Bitcoin_like');
1458
+ return (capabilities === null || capabilities === void 0 ? void 0 : capabilities.length) && !supportsBitcoinLike
1459
+ ? hdShared.EFirmwareType.BitcoinOnly
1460
+ : hdShared.EFirmwareType.Universal;
1461
+ };
1462
+ const resolveDeviceBleName = (features) => {
1463
+ var _a;
1464
+ if (!features)
1465
+ return null;
1466
+ const compatible = asCompatibleFeatures(features);
1467
+ return ((_a = firstNonEmptyString(compatible.bleName, compatible.onekey_ble_name, compatible.ble_name)) !== null && _a !== void 0 ? _a : null);
1468
+ };
1469
+ const resolveDeviceFirmwareVersion = (features) => {
1470
+ if (!features)
1471
+ return null;
1472
+ const compatible = asCompatibleFeatures(features);
1473
+ return firstMeaningfulVersion$1(compatible.firmwareVersion, compatible.onekey_firmware_version, compatible.onekey_version, versionFromParts(compatible.major_version, compatible.minor_version, compatible.patch_version));
1474
+ };
1475
+ const resolveDeviceBootloaderVersion = (features) => {
1476
+ var _a;
1477
+ if (!features)
1478
+ return null;
1479
+ const compatible = asCompatibleFeatures(features);
1480
+ const bootloaderMode = (_a = compatible.bootloaderMode) !== null && _a !== void 0 ? _a : compatible.bootloader_mode;
1481
+ return firstMeaningfulVersion$1(compatible.bootloaderVersion, compatible.onekey_boot_version, compatible.bootloader_version, compatible.onekey_bootloader_version, bootloaderMode
1482
+ ? versionFromParts(compatible.major_version, compatible.minor_version, compatible.patch_version)
1483
+ : null);
1484
+ };
1485
+ const resolveDeviceBoardVersion = (features) => {
1486
+ if (!features)
1487
+ return null;
1488
+ const compatible = asCompatibleFeatures(features);
1489
+ return firstMeaningfulVersion$1(compatible.boardVersion, compatible.onekey_board_version, compatible.boardloader_version, compatible.onekey_romloader_version, compatible.romloader_version);
1490
+ };
1491
+ const resolveDeviceBleFirmwareVersion = (features) => {
1492
+ if (!features)
1493
+ return null;
1494
+ const compatible = asCompatibleFeatures(features);
1495
+ return firstMeaningfulVersion$1(compatible.bleVersion, compatible.onekey_ble_version, compatible.ble_ver, compatible.onekey_coprocessor_version);
1496
+ };
1497
+
1498
+ const getDeviceType = (features) => resolveDeviceType(features);
1499
+ const getDeviceTypeByBleName = (name) => {
1500
+ if (!name)
1501
+ return hdShared.EDeviceType.Unknown;
1502
+ if (/^BixinKey/i.test(name))
1503
+ return hdShared.EDeviceType.Classic;
1504
+ if (/^K/i.test(name))
1505
+ return hdShared.EDeviceType.Classic;
1506
+ if (/^T/i.test(name))
1507
+ return hdShared.EDeviceType.Touch;
1508
+ if (/^Touch/i.test(name))
1509
+ return hdShared.EDeviceType.Touch;
1510
+ if (/\bPro\s*2\b/i.test(name) || /^Pro2/i.test(name))
1511
+ return hdShared.EDeviceType.Pro2;
1512
+ if (/\bPro\b/i.test(name) || /^Pro/i.test(name))
1513
+ return hdShared.EDeviceType.Pro;
1514
+ return hdShared.EDeviceType.Unknown;
1515
+ };
1516
+ const getDeviceBleName = (features) => resolveDeviceBleName(features);
1517
+ const getDeviceSerialNo = (features) => resolveDeviceSerialNo(features);
1518
+ const getDeviceUUID = getDeviceSerialNo;
1519
+ const getDeviceLabel = (features) => {
1520
+ if (!features)
1521
+ return null;
1522
+ const deviceType = getDeviceType(features);
1523
+ if (deviceType == null)
1524
+ return null;
1525
+ if ('label' in features && typeof features.label === 'string' && features.label.length > 0) {
1526
+ return features.label;
1527
+ }
1528
+ const bleName = getDeviceBleName(features);
1529
+ if (bleName)
1530
+ return bleName;
1531
+ if (deviceType === hdShared.EDeviceType.ClassicPure) {
1532
+ return 'OneKey Classic 1S';
1533
+ }
1534
+ return `OneKey ${deviceType.charAt(0).toUpperCase() + deviceType.slice(1)}`;
1535
+ };
1536
+ const getMethodVersionRange = (features, getVersionRange) => {
1537
+ const deviceType = getDeviceType(features);
1538
+ const versionRange = getVersionRange(deviceType);
1539
+ if (versionRange) {
1540
+ return versionRange;
1541
+ }
1542
+ const modelFallbacks = [
1543
+ 'model_classic1s',
1544
+ 'model_classic',
1545
+ 'model_mini',
1546
+ 'model_touch',
1547
+ ];
1548
+ for (const model of modelFallbacks) {
1549
+ if (DeviceModelToTypes[model].includes(deviceType)) {
1550
+ const versionRange = getVersionRange(model);
1551
+ if (versionRange) {
1552
+ return versionRange;
1553
+ }
1554
+ }
1555
+ }
1556
+ return undefined;
1557
+ };
1558
+ const isMethodVersionRangeUnsupported = (versionRange) => (versionRange === null || versionRange === void 0 ? void 0 : versionRange.unsupported) === true;
1559
+ const getFirmwareType = (features) => resolveDeviceFirmwareType(features);
1560
+
1561
+ const EMPTY_VERSION = [0, 0, 0];
1562
+ const parseDeviceVersion = (version) => {
1563
+ const parsed = version ? semver__default["default"].parse(version) : null;
1564
+ return parsed ? [parsed.major, parsed.minor, parsed.patch] : [...EMPTY_VERSION];
1565
+ };
1566
+ const getDeviceFirmwareVersion = (features) => parseDeviceVersion(resolveDeviceFirmwareVersion(features));
1567
+ const getDeviceBootloaderVersion = (features) => parseDeviceVersion(resolveDeviceBootloaderVersion(features));
1568
+ const getDeviceBoardloaderVersion = (features) => parseDeviceVersion(resolveDeviceBoardVersion(features));
1569
+ const getDeviceBLEFirmwareVersion = (features) => parseDeviceVersion(resolveDeviceBleFirmwareVersion(features));
1570
+
2477
1571
  const HD_HARDENED = 0x80000000;
2478
1572
  const toHardened = (n) => (n | HD_HARDENED) >>> 0;
2479
1573
  const fromHardened = (n) => (n & ~HD_HARDENED) >>> 0;
@@ -38249,6 +37343,33 @@ var nested = {
38249
37343
  }
38250
37344
  }
38251
37345
  },
37346
+ UiAnimationType: {
37347
+ values: {
37348
+ Unknown: 0,
37349
+ Signing: 1
37350
+ }
37351
+ },
37352
+ UiAnimationCommand: {
37353
+ values: {
37354
+ CommandUnknown: 0,
37355
+ Start: 1,
37356
+ Stop: 2,
37357
+ Refresh: 3
37358
+ }
37359
+ },
37360
+ UiAnimationRequest: {
37361
+ fields: {
37362
+ command: {
37363
+ rule: "required",
37364
+ type: "UiAnimationCommand",
37365
+ id: 1
37366
+ },
37367
+ type: {
37368
+ type: "UiAnimationType",
37369
+ id: 2
37370
+ }
37371
+ }
37372
+ },
38252
37373
  ViewAmount: {
38253
37374
  fields: {
38254
37375
  is_unlimited: {
@@ -39230,6 +38351,10 @@ var nested = {
39230
38351
  },
39231
38352
  DeviceSessionAskPassphrase: {
39232
38353
  fields: {
38354
+ passphrase: {
38355
+ type: "string",
38356
+ id: 1
38357
+ }
39233
38358
  }
39234
38359
  },
39235
38360
  DeviceSessionAskPin_FailureSubCodes: {
@@ -40404,19 +39529,9 @@ class DataManager {
40404
39529
  return enrichedData;
40405
39530
  }
40406
39531
  static load(settings) {
40407
- var _b;
40408
39532
  return __awaiter(this, void 0, void 0, function* () {
40409
39533
  this.settings = settings;
40410
- const manifestMode = (_b = settings.firmwareManifestMode) !== null && _b !== void 0 ? _b : (settings.fetchConfig ? 'sdk-managed' : undefined);
40411
- if (settings.preloadedConfig) {
40412
- this.applyRemoteConfig(settings.preloadedConfig);
40413
- Log$i.log('[DataConfig] Preloaded firmware config loaded');
40414
- return;
40415
- }
40416
- if (manifestMode === 'external-only') {
40417
- throw new Error('External firmware config snapshot is required');
40418
- }
40419
- if (manifestMode !== 'sdk-managed') {
39534
+ if (!settings.fetchConfig) {
40420
39535
  return;
40421
39536
  }
40422
39537
  const url = settings.preRelease
@@ -40424,50 +39539,57 @@ class DataManager {
40424
39539
  : 'https://data.onekey.so/config.json';
40425
39540
  const urlWithCache = `${url}?noCache=${getTimeStamp()}`;
40426
39541
  let data = null;
39542
+ let fetchMethod = 'none';
40427
39543
  if (settings.configFetcher) {
40428
- Log$i.debug('[DataConfig] Trying client configFetcher...');
39544
+ Log$i.debug('[DataConfig] Trying configFetcher (client-side fetcher)...');
40429
39545
  try {
40430
39546
  data = yield settings.configFetcher(urlWithCache);
39547
+ if (data) {
39548
+ fetchMethod = 'configFetcher';
39549
+ Log$i.log('[DataConfig] ConfigFetcher success');
39550
+ }
39551
+ else {
39552
+ Log$i.debug('[DataConfig] ConfigFetcher returned null, will fallback to axios');
39553
+ }
40431
39554
  }
40432
39555
  catch (e) {
40433
- Log$i.warn('[DataConfig] Client configFetcher failed:', e);
39556
+ Log$i.warn('[DataConfig] ConfigFetcher error, will fallback to axios:', e);
40434
39557
  }
40435
39558
  }
40436
39559
  if (!data) {
40437
- Log$i.debug('[DataConfig] Trying SDK-managed config request...');
39560
+ Log$i.debug('[DataConfig] Trying axios (SDK default fetcher)...');
40438
39561
  try {
40439
39562
  const response = yield axios__default["default"].get(urlWithCache, {
40440
39563
  timeout: 7000,
40441
39564
  });
40442
39565
  data = response.data;
40443
- Log$i.log('[DataConfig] SDK-managed config request succeeded');
39566
+ fetchMethod = 'axios';
39567
+ Log$i.log('[DataConfig] Axios fetch success');
40444
39568
  }
40445
39569
  catch (e) {
40446
- Log$i.warn('[DataConfig] SDK-managed config request failed:', e);
39570
+ Log$i.warn('[DataConfig] Axios fetch error:', e);
40447
39571
  }
40448
39572
  }
40449
39573
  if (data) {
40450
- this.applyRemoteConfig(data);
39574
+ Log$i.log(`[DataConfig] Config loaded successfully via [${fetchMethod}]`);
39575
+ this.deviceMap = {
39576
+ [hdShared.EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
39577
+ [hdShared.EDeviceType.Classic1s]: this.enrichFirmwareReleaseInfo(data.classic1s),
39578
+ [hdShared.EDeviceType.ClassicPure]: this.enrichFirmwareReleaseInfo(data.classicpure),
39579
+ [hdShared.EDeviceType.Mini]: this.enrichFirmwareReleaseInfo(data.mini),
39580
+ [hdShared.EDeviceType.Touch]: this.enrichFirmwareReleaseInfo(data.touch),
39581
+ [hdShared.EDeviceType.Pro]: this.enrichFirmwareReleaseInfo(data.pro),
39582
+ [hdShared.EDeviceType.Pro2]: this.enrichFirmwareReleaseInfo(data.pro2),
39583
+ };
39584
+ this.assets = {
39585
+ bridge: data.bridge,
39586
+ };
40451
39587
  }
40452
39588
  else {
40453
- Log$i.warn('[DataConfig] SDK-managed config request failed, using built-in default config');
39589
+ Log$i.warn('[DataConfig] All fetch methods failed, using built-in default config');
40454
39590
  }
40455
39591
  });
40456
39592
  }
40457
- static applyRemoteConfig(data) {
40458
- this.deviceMap = {
40459
- [hdShared.EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
40460
- [hdShared.EDeviceType.Classic1s]: this.enrichFirmwareReleaseInfo(data.classic1s),
40461
- [hdShared.EDeviceType.ClassicPure]: this.enrichFirmwareReleaseInfo(data.classicpure),
40462
- [hdShared.EDeviceType.Mini]: this.enrichFirmwareReleaseInfo(data.mini),
40463
- [hdShared.EDeviceType.Touch]: this.enrichFirmwareReleaseInfo(data.touch),
40464
- [hdShared.EDeviceType.Pro]: this.enrichFirmwareReleaseInfo(data.pro),
40465
- [hdShared.EDeviceType.Pro2]: this.enrichFirmwareReleaseInfo(data.pro2),
40466
- };
40467
- this.assets = {
40468
- bridge: data.bridge,
40469
- };
40470
- }
40471
39593
  static updateEnv(newEnv) {
40472
39594
  if (this.settings) {
40473
39595
  const prevEnv = this.settings.env;
@@ -40963,10 +40085,8 @@ const getDeviceSession = (device, request) => __awaiter(void 0, void 0, void 0,
40963
40085
  return device.commands.typedCall('DeviceSessionGet', 'DeviceSession', request);
40964
40086
  }
40965
40087
  });
40966
- const askDevicePassphrase = (device) => __awaiter(void 0, void 0, void 0, function* () {
40967
- const request = () => device.commands.typedCall('DeviceSessionAskPassphrase', 'Success', {}, {
40968
- timeoutMs: 120000,
40969
- });
40088
+ const askDevicePassphrase = (device, passphrase) => __awaiter(void 0, void 0, void 0, function* () {
40089
+ const request = () => device.commands.typedCall('DeviceSessionAskPassphrase', 'Success', passphrase ? { passphrase } : {});
40970
40090
  try {
40971
40091
  return yield request();
40972
40092
  }
@@ -40985,7 +40105,7 @@ const selectDeviceSession = (device) => __awaiter(void 0, void 0, void 0, functi
40985
40105
  source: 'wallet-session-coordinator',
40986
40106
  reason: 'open-wallet',
40987
40107
  };
40988
- const response = yield device.commands.promptPassphrase(Object.assign({ existsAttachPinUser, deviceOnly: true }, metadata), { cancelDeviceOnReject: false });
40108
+ const response = yield device.commands.promptPassphrase(Object.assign({ existsAttachPinUser }, metadata), { cancelDeviceOnReject: false });
40989
40109
  const hasHostPassphrase = typeof response.passphrase === 'string' && response.passphrase.length > 0;
40990
40110
  const selections = [
40991
40111
  hasHostPassphrase,
@@ -41003,6 +40123,10 @@ const selectDeviceSession = (device) => __awaiter(void 0, void 0, void 0, functi
41003
40123
  yield device.unlockDevice(hdTransport.DeviceSessionPinType.AttachToPin);
41004
40124
  return getDeviceSession(device, {});
41005
40125
  }
40126
+ if (hasHostPassphrase) {
40127
+ yield askDevicePassphrase(device, response.passphrase);
40128
+ return getDeviceSession(device, {});
40129
+ }
41006
40130
  device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, metadata);
41007
40131
  yield askDevicePassphrase(device);
41008
40132
  return getDeviceSession(device, {});
@@ -41046,6 +40170,10 @@ function getProtocolV2WalletSession(device, options) {
41046
40170
  }
41047
40171
  }
41048
40172
  if (!response) {
40173
+ if (options === null || options === void 0 ? void 0 : options.resumeOnly) {
40174
+ device.clearInternalState();
40175
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid);
40176
+ }
41049
40177
  response = yield selectDeviceSession(device);
41050
40178
  }
41051
40179
  const { message } = response;
@@ -41069,6 +40197,14 @@ function getProtocolV2WalletSession(device, options) {
41069
40197
  };
41070
40198
  });
41071
40199
  }
40200
+ function restoreProtocolV2WalletSession(device, expectedPassphraseState) {
40201
+ return __awaiter(this, void 0, void 0, function* () {
40202
+ return getProtocolV2WalletSession(device, {
40203
+ expectedPassphraseState,
40204
+ resumeOnly: true,
40205
+ });
40206
+ });
40207
+ }
41072
40208
 
41073
40209
  const getSupportProtocolV1MessageSchema = (features) => {
41074
40210
  var _a;
@@ -41404,16 +40540,9 @@ const parseConnectSettings = (input = {}) => {
41404
40540
  if (input.fetchConfig) {
41405
40541
  settings.fetchConfig = input.fetchConfig;
41406
40542
  }
41407
- if (input.firmwareManifestMode === 'sdk-managed' ||
41408
- input.firmwareManifestMode === 'external-only') {
41409
- settings.firmwareManifestMode = input.firmwareManifestMode;
41410
- }
41411
40543
  if (input.configFetcher) {
41412
40544
  settings.configFetcher = input.configFetcher;
41413
40545
  }
41414
- if (input.preloadedConfig) {
41415
- settings.preloadedConfig = input.preloadedConfig;
41416
- }
41417
40546
  return settings;
41418
40547
  };
41419
40548
 
@@ -41476,7 +40605,8 @@ function checkNeedUpdateBootForClassicAndMini({ features, willUpdateFirmware, fi
41476
40605
  });
41477
40606
  }
41478
40607
  const INIT_DATA_CHUNK_SIZE$1 = 16 * 1024;
41479
- const readBootloaderLength = (chunk) => {
40608
+ function checkBootloaderLength(data) {
40609
+ const chunk = new Uint8Array(data.slice(0, Math.min(INIT_DATA_CHUNK_SIZE$1, data.byteLength)));
41480
40610
  const buffer = ByteBuffer__default["default"].wrap(chunk, undefined, undefined, true);
41481
40611
  buffer.LE();
41482
40612
  buffer.readByte();
@@ -41486,22 +40616,9 @@ const readBootloaderLength = (chunk) => {
41486
40616
  const hdrlen = buffer.readUint32();
41487
40617
  buffer.readUint32();
41488
40618
  const codelen = buffer.readUint32();
41489
- return hdrlen + codelen;
41490
- };
41491
- function checkBootloaderLength(data) {
41492
- if (data.byteLength < 16) {
41493
- return false;
41494
- }
41495
- const chunk = new Uint8Array(data.slice(0, Math.min(INIT_DATA_CHUNK_SIZE$1, data.byteLength)));
41496
- return readBootloaderLength(chunk) === data.byteLength;
40619
+ const bootloaderLength = hdrlen + codelen;
40620
+ return bootloaderLength === data.byteLength;
41497
40621
  }
41498
- const checkBootloaderSourceLength = (source) => __awaiter(void 0, void 0, void 0, function* () {
41499
- if (source.size < 16) {
41500
- return false;
41501
- }
41502
- const chunk = new Uint8Array(yield source.readAt(0, Math.min(INIT_DATA_CHUNK_SIZE$1, source.size)));
41503
- return readBootloaderLength(chunk) === source.size;
41504
- });
41505
40622
 
41506
40623
  const DEVICE_SETTINGS_SHARED_FIELDS = [
41507
40624
  'language',
@@ -42824,6 +41941,23 @@ class DeviceCommands {
42824
41941
  firmwareMessage: message,
42825
41942
  });
42826
41943
  }
41944
+ else if (DEVICE_SESSION_CALLS.has(callType) &&
41945
+ (subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_Busy ||
41946
+ /^(?:busy|another flow in progress)$/i.test(normalizedMessage))) {
41947
+ error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceBusy, message, {
41948
+ failureCode: code,
41949
+ subcode,
41950
+ firmwareMessage: message,
41951
+ });
41952
+ }
41953
+ else if (callType === 'DeviceSessionAskPin' &&
41954
+ /^passphrase disabled$/i.test(normalizedMessage)) {
41955
+ error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotOpenedPassphrase, message, {
41956
+ failureCode: code,
41957
+ subcode,
41958
+ firmwareMessage: message,
41959
+ });
41960
+ }
42827
41961
  else if (subcode === hdTransport.DeviceErrorCode.DeviceError_ActionCancelled ||
42828
41962
  isLegacyProtocolV2ActionCancelledFailure) {
42829
41963
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, message, {
@@ -43835,6 +42969,10 @@ class Device extends events.exports {
43835
42969
  const env = DataManager.getSettings('env');
43836
42970
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
43837
42971
  if (DataManager.isBleConnect(env)) {
42972
+ if (this.hasDeviceAcquire() && this.commands && !this.commands.disposed) {
42973
+ resolve(true);
42974
+ return;
42975
+ }
43838
42976
  try {
43839
42977
  yield this.acquire(connectProtocol);
43840
42978
  resolve(true);
@@ -44415,6 +43553,7 @@ class Device extends events.exports {
44415
43553
  return this.updateProtocolV2Features(previousDeviceInfo, Object.assign(Object.assign({}, previousStatus), status));
44416
43554
  }
44417
43555
  markTransportDisconnected() {
43556
+ this.deviceAcquired = false;
44418
43557
  if (!this.isProtocolV2())
44419
43558
  return;
44420
43559
  this.protocolV2StateNeedsReload = true;
@@ -44665,7 +43804,7 @@ class Device extends events.exports {
44665
43804
  isUsedHere() {
44666
43805
  const env = DataManager.getSettings('env');
44667
43806
  if (DataManager.isBleConnect(env)) {
44668
- return false;
43807
+ return this.deviceAcquired;
44669
43808
  }
44670
43809
  return this.isUsed() && this.originalDescriptor.session === this.mainId;
44671
43810
  }
@@ -44734,9 +43873,7 @@ class Device extends events.exports {
44734
43873
  return __awaiter(this, void 0, void 0, function* () {
44735
43874
  if (this.isProtocolV2()) {
44736
43875
  try {
44737
- yield this.commands.typedCall('DeviceSessionAskPin', 'Success', { type: pinType }, {
44738
- timeoutMs: 120000,
44739
- });
43876
+ yield this.commands.typedCall('DeviceSessionAskPin', 'Success', { type: pinType });
44740
43877
  }
44741
43878
  catch (error) {
44742
43879
  const errorText = error instanceof Error
@@ -45241,6 +44378,46 @@ class TestInitializeDeviceDuration extends BaseMethod {
45241
44378
  }
45242
44379
  }
45243
44380
 
44381
+ const PROTOCOL_V2_PING_MAX_MESSAGE_BYTES = 63;
44382
+ const getUtf8ByteLength$1 = (value) => Array.from(value).reduce((length, character) => {
44383
+ var _a;
44384
+ const codePoint = (_a = character.codePointAt(0)) !== null && _a !== void 0 ? _a : 0;
44385
+ if (codePoint <= 0x7f)
44386
+ return length + 1;
44387
+ if (codePoint <= 0x7ff)
44388
+ return length + 2;
44389
+ if (codePoint <= 0xffff)
44390
+ return length + 3;
44391
+ return length + 4;
44392
+ }, 0);
44393
+ function validateProtocolV2PingMessage(value) {
44394
+ if (value !== undefined && typeof value !== 'string') {
44395
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 Ping message must be a string.');
44396
+ }
44397
+ const message = value !== null && value !== void 0 ? value : '';
44398
+ if (getUtf8ByteLength$1(message) > PROTOCOL_V2_PING_MAX_MESSAGE_BYTES) {
44399
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, `Protocol V2 Ping message must not exceed ${PROTOCOL_V2_PING_MAX_MESSAGE_BYTES} UTF-8 bytes.`);
44400
+ }
44401
+ return message;
44402
+ }
44403
+ class Ping extends BaseMethod {
44404
+ init() {
44405
+ this.requireProtocolV2 = true;
44406
+ this.skipForceUpdateCheck = true;
44407
+ this.useDevicePassphraseState = false;
44408
+ this.params = { message: validateProtocolV2PingMessage(this.payload.message) };
44409
+ }
44410
+ run() {
44411
+ var _a;
44412
+ return __awaiter(this, void 0, void 0, function* () {
44413
+ const res = yield this.device.commands.typedCall('Ping', 'Success', {
44414
+ message: (_a = this.params.message) !== null && _a !== void 0 ? _a : '',
44415
+ });
44416
+ return Promise.resolve(res.message);
44417
+ });
44418
+ }
44419
+ }
44420
+
45244
44421
  const Log$c = getLogger(exports.LoggerNames.Core);
45245
44422
  const parseInitOptions$1 = (payload) => ({
45246
44423
  initSession: payload === null || payload === void 0 ? void 0 : payload.initSession,
@@ -45629,12 +44806,6 @@ const requiredString = (value, name) => {
45629
44806
  }
45630
44807
  return value.trim();
45631
44808
  };
45632
- const optionalBoolean = (value, name) => {
45633
- if (value !== undefined && typeof value !== 'boolean') {
45634
- throw invalidParameter$1(`Parameter [${name}] must be a boolean.`);
45635
- }
45636
- return value;
45637
- };
45638
44809
  const wasResumed = (session) => !!session &&
45639
44810
  typeof session === 'object' &&
45640
44811
  'resumed' in session &&
@@ -45647,49 +44818,22 @@ const requireHiddenWalletResponse = (session) => {
45647
44818
  return Object.assign({ passphraseState: session.passphraseState }, forwardSessionId(session));
45648
44819
  };
45649
44820
  const normalizeParams = (payload) => {
45650
- if (payload.mode !== undefined) {
45651
- if (payload.mode !== 'standard' &&
45652
- payload.mode !== 'select-hidden' &&
45653
- payload.mode !== 'resume-hidden') {
45654
- throw invalidParameter$1('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
45655
- }
45656
- if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
45657
- throw invalidParameter$1('Parameters [useEmptyPassphrase] and [initSession] cannot be used with [mode].');
45658
- }
45659
- if (payload.mode === 'standard' || payload.mode === 'select-hidden') {
45660
- if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
45661
- throw invalidParameter$1('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
45662
- }
45663
- return { mode: payload.mode };
45664
- }
45665
- return {
45666
- mode: 'resume-hidden',
45667
- deviceId: requiredString(payload.deviceId, 'deviceId'),
45668
- passphraseState: requiredString(payload.passphraseState, 'passphraseState'),
45669
- };
44821
+ if (payload.mode === undefined) {
44822
+ throw invalidParameter$1('Parameter [mode] is required.');
45670
44823
  }
45671
- const useEmptyPassphrase = optionalBoolean(payload.useEmptyPassphrase, 'useEmptyPassphrase');
45672
- const initSession = optionalBoolean(payload.initSession, 'initSession');
45673
- if (useEmptyPassphrase === true) {
45674
- return { mode: 'standard' };
44824
+ if (payload.mode !== 'standard' &&
44825
+ payload.mode !== 'select-hidden' &&
44826
+ payload.mode !== 'resume-hidden') {
44827
+ throw invalidParameter$1('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
45675
44828
  }
45676
- if (initSession === true) {
45677
- const deviceId = payload.deviceId === undefined ? undefined : requiredString(payload.deviceId, 'deviceId');
45678
- const passphraseState = payload.passphraseState === undefined
45679
- ? undefined
45680
- : requiredString(payload.passphraseState, 'passphraseState');
45681
- return Object.assign({ mode: 'select-hidden' }, (passphraseState
45682
- ? {
45683
- legacySessionToClear: {
45684
- deviceId,
45685
- passphraseState,
45686
- },
45687
- }
45688
- : {}));
44829
+ if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
44830
+ throw invalidParameter$1('Legacy parameters [useEmptyPassphrase] and [initSession] are not supported by openWalletSession.');
45689
44831
  }
45690
- const hasWalletBinding = payload.deviceId !== undefined || payload.passphraseState !== undefined;
45691
- if (!hasWalletBinding) {
45692
- return { mode: 'select-hidden' };
44832
+ if (payload.mode === 'standard' || payload.mode === 'select-hidden') {
44833
+ if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
44834
+ throw invalidParameter$1('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
44835
+ }
44836
+ return { mode: payload.mode };
45693
44837
  }
45694
44838
  return {
45695
44839
  mode: 'resume-hidden',
@@ -45710,29 +44854,17 @@ class OpenWalletSession extends BaseMethod {
45710
44854
  const isProtocolV2 = this.device.isProtocolV2();
45711
44855
  const state = yield this.device.getDeviceState({ refreshSections: ['status'] });
45712
44856
  let currentDeviceId = state.identity.deviceId;
45713
- const { legacySessionToClear } = this.params;
45714
44857
  const requireDeviceId = () => {
45715
44858
  if (!currentDeviceId) {
45716
44859
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
45717
44860
  }
45718
44861
  return currentDeviceId;
45719
44862
  };
45720
- const clearLegacySession = () => {
45721
- const deviceId = requireDeviceId();
45722
- if (legacySessionToClear &&
45723
- (!legacySessionToClear.deviceId || legacySessionToClear.deviceId === deviceId)) {
45724
- deviceWalletSessionStore.delete(deviceId, legacySessionToClear.passphraseState);
45725
- }
45726
- };
45727
44863
  const refreshProtocolV2DeviceId = () => __awaiter(this, void 0, void 0, function* () {
45728
44864
  const refreshedState = yield this.device.getDeviceState({ refreshSections: ['status'] });
45729
44865
  currentDeviceId = refreshedState.identity.deviceId;
45730
- clearLegacySession();
45731
44866
  return requireDeviceId();
45732
44867
  });
45733
- if (!isProtocolV2) {
45734
- clearLegacySession();
45735
- }
45736
44868
  const protocol = isProtocolV2 ? 'V2' : 'V1';
45737
44869
  if (this.params.mode === 'standard') {
45738
44870
  this.device.passphraseState = undefined;
@@ -46049,7 +45181,8 @@ class CheckAllFirmwareRelease extends BaseMethod {
46049
45181
  var _a, _b;
46050
45182
  return __awaiter(this, void 0, void 0, function* () {
46051
45183
  const { features } = this.device;
46052
- const { checkBridgeRelease, firmwareType: firmwareTypeParams, platform, } = this.payload;
45184
+ const { checkBridgeRelease, firmwareType: firmwareTypeParams } = this
45185
+ .payload;
46053
45186
  if (!features) {
46054
45187
  return Promise.resolve(null);
46055
45188
  }
@@ -46074,20 +45207,6 @@ class CheckAllFirmwareRelease extends BaseMethod {
46074
45207
  firmwareType,
46075
45208
  });
46076
45209
  const bleFirmwareReleaseInfo = getBleFirmwareReleaseInfo(features);
46077
- let firmwareUpdatePlan;
46078
- try {
46079
- firmwareUpdatePlan = buildFirmwareUpdatePlan({
46080
- features,
46081
- firmwareType,
46082
- platform: platform !== null && platform !== void 0 ? platform : 'web',
46083
- firmware: firmwareRelease,
46084
- ble: bleFirmwareReleaseInfo,
46085
- bootloader: bootloaderRelease,
46086
- });
46087
- }
46088
- catch (_c) {
46089
- firmwareUpdatePlan = undefined;
46090
- }
46091
45210
  return {
46092
45211
  firmware: firmwareRelease,
46093
45212
  bootloader: bootloaderRelease,
@@ -46101,7 +45220,6 @@ class CheckAllFirmwareRelease extends BaseMethod {
46101
45220
  }
46102
45221
  : undefined,
46103
45222
  features,
46104
- firmwareUpdatePlan,
46105
45223
  };
46106
45224
  });
46107
45225
  }
@@ -46985,13 +46103,7 @@ const waitBleInstall = (updateType) => __awaiter(void 0, void 0, void 0, functio
46985
46103
  yield wait(10 * 1000);
46986
46104
  }
46987
46105
  });
46988
- const toArrayBuffer$1 = (payload) => {
46989
- if (payload instanceof ArrayBuffer) {
46990
- return payload;
46991
- }
46992
- return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength).slice().buffer;
46993
- };
46994
- const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, source, rebootOnSuccess, isUpdateBootloader) => __awaiter(void 0, void 0, void 0, function* () {
46106
+ const uploadFirmware = (updateType, typedCall, postMessage, device, { payload, rebootOnSuccess, }, isUpdateBootloader) => __awaiter(void 0, void 0, void 0, function* () {
46995
46107
  var _a, _b;
46996
46108
  const deviceType = device.getCurrentDeviceType();
46997
46109
  if (DeviceModelToTypes.model_mini.includes(deviceType)) {
@@ -47005,15 +46117,15 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47005
46117
  Log$a.debug('supportUpgradeFileHeader:', supportUpgradeFileHeader);
47006
46118
  if (supportUpgradeFileHeader) {
47007
46119
  const HEADER_SIZE = 1024;
47008
- if (source.size < HEADER_SIZE) {
47009
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `firmware payload too small: ${source.size} bytes, expected at least ${HEADER_SIZE} bytes`);
46120
+ if (payload.byteLength < HEADER_SIZE) {
46121
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `firmware payload too small: ${payload.byteLength} bytes, expected at least ${HEADER_SIZE} bytes`);
47010
46122
  }
47011
46123
  Log$a.debug('Uploading firmware header:', {
47012
46124
  size: HEADER_SIZE,
47013
- totalSize: source.size,
46125
+ totalSize: payload.byteLength,
47014
46126
  });
47015
46127
  postProgressTip(device, 'UploadingFirmwareHeader', postMessage);
47016
- const header = new Uint8Array(yield source.readAt(0, HEADER_SIZE));
46128
+ const header = new Uint8Array(payload.slice(0, HEADER_SIZE));
47017
46129
  try {
47018
46130
  const headerRes = yield typedCall('UpgradeFileHeader', 'Success', {
47019
46131
  data: bytesToHex$1(header),
@@ -47043,7 +46155,6 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47043
46155
  postProgressMessage(device, 0, 'installingFirmware', postMessage);
47044
46156
  let updateResponse;
47045
46157
  try {
47046
- const payload = yield readFirmwareByteSourceFully(source);
47047
46158
  updateResponse = yield typedCall('FirmwareUpload', 'Success', {
47048
46159
  payload,
47049
46160
  });
@@ -47071,19 +46182,21 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47071
46182
  if (device.features) {
47072
46183
  const bootloaderVersion = getDeviceBootloaderVersion(device.features);
47073
46184
  if (semver__default["default"].gte(bootloaderVersion.join('.'), NEW_BOOT_UPRATE_FIRMWARE_VERSION)) {
47074
- const response = yield newTouchUpdateProcess(updateType, postMessage, device, source, rebootOnSuccess);
46185
+ const response = yield newTouchUpdateProcess(updateType, postMessage, device, {
46186
+ payload,
46187
+ }, rebootOnSuccess);
47075
46188
  return response.message;
47076
46189
  }
47077
46190
  }
47078
46191
  postConfirmationMessage(device);
47079
46192
  postProgressTip(device, 'ConfirmOnDevice', postMessage);
47080
- const length = source.size;
46193
+ const length = payload.byteLength;
47081
46194
  let response = yield typedCall('FirmwareErase', ['FirmwareRequest', 'Success'], { length });
47082
46195
  postProgressTip(device, 'FirmwareEraseSuccess', postMessage);
47083
46196
  while (response.type !== 'Success') {
47084
46197
  const start = response.message.offset;
47085
46198
  const end = response.message.offset + response.message.length;
47086
- const chunk = yield source.readAt(start, end - start);
46199
+ const chunk = payload.slice(start, end);
47087
46200
  if (start > 0) {
47088
46201
  postProgressMessage(device, Math.round((start / length) * 100), 'transferData', postMessage);
47089
46202
  }
@@ -47100,21 +46213,7 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47100
46213
  }
47101
46214
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'uploadFirmware: unknown device model');
47102
46215
  });
47103
- const uploadFirmware = (updateType, typedCall, postMessage, device, { payload, rebootOnSuccess, }, isUpdateBootloader) => __awaiter(void 0, void 0, void 0, function* () {
47104
- const source = yield openFirmwareByteSource({
47105
- binary: toArrayBuffer$1(payload),
47106
- });
47107
- if (!source) {
47108
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'firmware payload is empty');
47109
- }
47110
- try {
47111
- return yield uploadFirmwareFromSource(updateType, typedCall, postMessage, device, source, rebootOnSuccess, isUpdateBootloader);
47112
- }
47113
- finally {
47114
- yield source.close();
47115
- }
47116
- });
47117
- const newTouchUpdateProcess = (updateType, postMessage, device, source, rebootOnSuccess = true) => __awaiter(void 0, void 0, void 0, function* () {
46216
+ const newTouchUpdateProcess = (updateType, postMessage, device, { payload }, rebootOnSuccess = true) => __awaiter(void 0, void 0, void 0, function* () {
47118
46217
  var _c, _d, _e, _f, _g;
47119
46218
  let typedCall = device.getCommands().typedCall.bind(device.getCommands());
47120
46219
  postProgressTip(device, 'StartTransferData', postMessage);
@@ -47122,13 +46221,13 @@ const newTouchUpdateProcess = (updateType, postMessage, device, source, rebootOn
47122
46221
  const env = DataManager.getSettings('env');
47123
46222
  const perPackageSize = DataManager.isBleConnect(env) ? 16 : 128;
47124
46223
  const chunkSize = 1024 * perPackageSize;
47125
- const totalChunks = Math.ceil(source.size / chunkSize);
46224
+ const totalChunks = Math.ceil(payload.byteLength / chunkSize);
47126
46225
  let offset = 0;
47127
46226
  for (let i = 0; i < totalChunks; i++) {
47128
46227
  const chunkStart = i * chunkSize;
47129
- const chunkEnd = Math.min(chunkStart + chunkSize, source.size);
46228
+ const chunkEnd = Math.min(chunkStart + chunkSize, payload.byteLength);
47130
46229
  const chunkLength = chunkEnd - chunkStart;
47131
- const chunk = yield source.readAt(chunkStart, chunkLength);
46230
+ const chunk = payload.slice(chunkStart, chunkEnd);
47132
46231
  const overwrite = i === 0;
47133
46232
  const progress = Math.round(((i + 1) / totalChunks) * 100);
47134
46233
  const writeRes = yield emmcFileWriteWithRetry(device, filePath, chunkLength, offset, chunk, overwrite, progress);
@@ -47296,44 +46395,6 @@ const updateResource = (typedCall, fileName, data, onConfirmAfter) => __awaiter(
47296
46395
  onConfirmAfter === null || onConfirmAfter === void 0 ? void 0 : onConfirmAfter();
47297
46396
  return processResourceRequest(typedCall, res, data);
47298
46397
  });
47299
- const updateResourceFromSource = (typedCall, fileName, source, onConfirmAfter) => __awaiter(void 0, void 0, void 0, function* () {
47300
- const initialLength = Math.min(INIT_DATA_CHUNK_SIZE, source.size);
47301
- const initialChunk = new Uint8Array(yield source.readAt(0, initialLength));
47302
- let response = yield typedCall('ResourceUpdate', ['ResourceRequest', 'Success'], {
47303
- file_name: fileName,
47304
- data_length: source.size,
47305
- initial_data_chunk: bytesToHex$1(initialChunk),
47306
- hash: bytesToHex$1(blake2s.blake2s(initialChunk)),
47307
- });
47308
- onConfirmAfter === null || onConfirmAfter === void 0 ? void 0 : onConfirmAfter();
47309
- while (response.type !== 'Success') {
47310
- const { offset, data_length: dataLength } = response.message;
47311
- if (!Number.isSafeInteger(offset) ||
47312
- offset === undefined ||
47313
- offset < 0 ||
47314
- !Number.isSafeInteger(dataLength) ||
47315
- dataLength === undefined ||
47316
- dataLength <= 0 ||
47317
- offset + dataLength > source.size) {
47318
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Device requested an invalid firmware resource range');
47319
- }
47320
- const chunk = new Uint8Array(yield source.readAt(offset, dataLength));
47321
- response = yield typedCall('ResourceAck', ['ResourceRequest', 'Success'], {
47322
- data_chunk: bytesToHex$1(chunk),
47323
- hash: bytesToHex$1(blake2s.blake2s(chunk)),
47324
- });
47325
- }
47326
- return response.message;
47327
- });
47328
- const updateResourcesFromSources = (typedCall, postMessage, device, entries) => __awaiter(void 0, void 0, void 0, function* () {
47329
- postProgressTip(device, 'UpdateSysResource', postMessage);
47330
- for (const [index, entry] of entries.entries()) {
47331
- yield updateResourceFromSource(typedCall, entry.entryName, entry.source);
47332
- postProgressMessage(device, Math.floor(((index + 1) / entries.length) * 100), 'installingFirmware', postMessage);
47333
- }
47334
- postProgressTip(device, 'UpdateSysResourceSuccess', postMessage);
47335
- return true;
47336
- });
47337
46398
  const updateResources = (typedCall, postMessage, device, source) => __awaiter(void 0, void 0, void 0, function* () {
47338
46399
  postProgressTip(device, 'UpdateSysResource', postMessage);
47339
46400
  const zipData = yield JSZip__default["default"].loadAsync(source);
@@ -47353,22 +46414,10 @@ const updateResources = (typedCall, postMessage, device, source) => __awaiter(vo
47353
46414
  postProgressTip(device, 'UpdateSysResourceSuccess', postMessage);
47354
46415
  return true;
47355
46416
  });
47356
- const updateBootloader = (typedCall, postMessage, device, data) => __awaiter(void 0, void 0, void 0, function* () {
47357
- const source = yield openFirmwareByteSource({ binary: data });
47358
- if (!source) {
47359
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'bootloader payload is empty');
47360
- }
47361
- try {
47362
- return yield updateBootloaderFromSource(typedCall, postMessage, device, source);
47363
- }
47364
- finally {
47365
- yield source.close();
47366
- }
47367
- });
47368
- const updateBootloaderFromSource = (typedCall, postMessage, device, source) => __awaiter(void 0, void 0, void 0, function* () {
46417
+ const updateBootloader = (typedCall, postMessage, device, source) => __awaiter(void 0, void 0, void 0, function* () {
47369
46418
  postProgressTip(device, 'UpdateBootloader', postMessage);
47370
46419
  postProgressMessage(device, Math.floor(0), 'installingFirmware', postMessage);
47371
- yield updateResourceFromSource(typedCall, 'bootloader.bin', source, () => {
46420
+ yield updateResource(typedCall, 'bootloader.bin', source, () => {
47372
46421
  postProcessingMessage('resource', postMessage);
47373
46422
  });
47374
46423
  postProgressMessage(device, Math.floor(100), 'installingFirmware', postMessage);
@@ -47734,32 +46783,6 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
47734
46783
  return totalSize !== undefined ? (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + payload.byteLength : 0;
47735
46784
  });
47736
46785
  }
47737
- emmcCommonUpdateProcessFromSource({ source, filePath, processedSize, totalSize, }) {
47738
- return __awaiter(this, void 0, void 0, function* () {
47739
- if (!filePath.startsWith('0:')) {
47740
- throw new Error('filePath must start with 0:');
47741
- }
47742
- const env = DataManager.getSettings('env');
47743
- const chunkSize = 1024 * (DataManager.isBleConnect(env) ? 16 : 128);
47744
- yield writeFirmwareByteSource({
47745
- source,
47746
- chunkSize,
47747
- write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
47748
- const progress = totalSize !== undefined && processedSize !== undefined
47749
- ? Math.min(Math.ceil(((processedSize + sourceOffset + length) / totalSize) * 100), 99)
47750
- : Math.min(Math.ceil(((sourceOffset + length) / source.size) * 100), 99);
47751
- const writeRes = yield this.emmcFileWriteWithRetry(filePath, length, sourceOffset, data, first, progress);
47752
- if (!writeRes) {
47753
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
47754
- }
47755
- const processedBytes = Number(writeRes.message.processed_byte);
47756
- this.postProgressMessage(progress, 'transferData');
47757
- return Number.isFinite(processedBytes) ? processedBytes : length;
47758
- }),
47759
- });
47760
- return totalSize !== undefined ? (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + source.size : 0;
47761
- });
47762
- }
47763
46786
  emmcFileWriteWithRetry(filePath, chunkLength, offset, chunk, overwrite, progress) {
47764
46787
  var _a, _b, _c, _d, _e, _f, _g, _h;
47765
46788
  return __awaiter(this, void 0, void 0, function* () {
@@ -47864,44 +46887,10 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
47864
46887
  return true;
47865
46888
  });
47866
46889
  }
47867
- updateBootloaderWithEmmcFileWriteFromSource(_device, source) {
46890
+ updateTouchBootloader({ device, features, firmwareType, }) {
47868
46891
  return __awaiter(this, void 0, void 0, function* () {
47869
- const filePath = '0:boot/bootloader.bin';
47870
- this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
47871
- yield this.emmcCommonUpdateProcessFromSource({
47872
- source,
47873
- filePath,
47874
- });
47875
- this.postTipMessage(exports.FirmwareUpdateTipMessage.ConfirmOnDevice);
47876
- yield this.reboot(hdTransport.RebootType.Normal);
47877
- this.postTipMessage(exports.FirmwareUpdateTipMessage.UpdateBootloaderSuccess);
47878
- return true;
47879
- });
47880
- }
47881
- updateTouchBootloader({ device, features, firmwareType, binary: preparedBinary, source: preparedSource, }) {
47882
- return __awaiter(this, void 0, void 0, function* () {
47883
- if (preparedSource) {
47884
- if (!(yield checkBootloaderSourceLength(preparedSource))) {
47885
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CheckDownloadFileError);
47886
- }
47887
- if (features && device.isBootloader()) {
47888
- this.postTipMessage(exports.FirmwareUpdateTipMessage.UpdateBootloader);
47889
- const result = yield this.updateBootloaderWithEmmcFileWriteFromSource(device, preparedSource);
47890
- return result;
47891
- }
47892
- if (features && !device.isBootloader()) {
47893
- yield updateBootloaderFromSource(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, preparedSource);
47894
- return true;
47895
- }
47896
- }
47897
- let binary = preparedBinary;
46892
+ let { binary } = this.payload;
47898
46893
  if (!binary) {
47899
- if (DataManager.getSettings('firmwareManifestMode') === 'external-only') {
47900
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Bootloader must be prepared by the external firmware host', {
47901
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
47902
- artifactName: 'bootloader',
47903
- });
47904
- }
47905
46894
  this.postTipMessage(exports.FirmwareUpdateTipMessage.CheckLatestUiResource);
47906
46895
  const resourceUrl = features
47907
46896
  ? DataManager.getBootloaderResource(features, firmwareType)
@@ -47915,13 +46904,12 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
47915
46904
  }
47916
46905
  }
47917
46906
  }
47918
- if (!binary || !checkBootloaderLength(binary)) {
46907
+ if (!checkBootloaderLength(binary)) {
47919
46908
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CheckDownloadFileError);
47920
46909
  }
47921
46910
  if (features && device.isBootloader()) {
47922
46911
  this.postTipMessage(exports.FirmwareUpdateTipMessage.UpdateBootloader);
47923
- const result = yield this.updateBootloaderWithEmmcFileWrite(device, binary);
47924
- return result;
46912
+ return this.updateBootloaderWithEmmcFileWrite(device, binary);
47925
46913
  }
47926
46914
  if (features && !device.isBootloader()) {
47927
46915
  yield updateBootloader(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, binary);
@@ -47930,67 +46918,16 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
47930
46918
  });
47931
46919
  }
47932
46920
  run() {
47933
- var _a, _b, _c;
46921
+ var _a;
47934
46922
  return __awaiter(this, void 0, void 0, function* () {
47935
46923
  const { device } = this;
47936
46924
  const { features } = device;
47937
46925
  const payload = this.payload;
47938
- const hostBinding = payload.artifact
47939
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
47940
- : undefined;
47941
- const executionParams = Object.assign(Object.assign({}, payload), { artifactReader: (_a = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _a !== void 0 ? _a : payload.artifactReader });
47942
- if (payload.artifact) {
47943
- assertFirmwareUpdatePreparedPlanDeviceIdentity({
47944
- preparedPlan: payload.preparedPlan,
47945
- deviceIdentity: getDeviceUUID(features) || undefined,
47946
- });
47947
- assertFirmwareUpdatePreparedPlanBinding({
47948
- preparedPlan: payload.preparedPlan,
47949
- executor: 'v2',
47950
- scopeTargets: ['bootloader'],
47951
- bindings: [
47952
- {
47953
- target: 'bootloader',
47954
- artifact: payload.artifact,
47955
- },
47956
- ],
47957
- });
47958
- const source = yield openFirmwareByteSource({
47959
- artifact: payload.artifact,
47960
- reader: executionParams.artifactReader,
47961
- });
47962
- if (!source) {
47963
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Bootloader artifact is not prepared');
47964
- }
47965
- try {
47966
- const deviceType = device.getCurrentDeviceType();
47967
- const deviceFirmwareType = device.getCurrentFirmwareType();
47968
- const firmwareType = (_b = payload.firmwareType) !== null && _b !== void 0 ? _b : deviceFirmwareType;
47969
- if (DeviceModelToTypes.model_touch.includes(deviceType)) {
47970
- return yield this.updateTouchBootloader({
47971
- device,
47972
- features,
47973
- firmwareType,
47974
- source,
47975
- });
47976
- }
47977
- return true;
47978
- }
47979
- finally {
47980
- yield source.close();
47981
- }
47982
- }
47983
- const { binary } = payload;
47984
46926
  const deviceType = device.getCurrentDeviceType();
47985
46927
  const deviceFirmwareType = device.getCurrentFirmwareType();
47986
- const firmwareType = (_c = payload.firmwareType) !== null && _c !== void 0 ? _c : deviceFirmwareType;
46928
+ const firmwareType = (_a = payload.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
47987
46929
  if (DeviceModelToTypes.model_touch.includes(deviceType)) {
47988
- return this.updateTouchBootloader({
47989
- device,
47990
- features,
47991
- firmwareType,
47992
- binary,
47993
- });
46930
+ return this.updateTouchBootloader({ device, features, firmwareType });
47994
46931
  }
47995
46932
  return Promise.resolve(true);
47996
46933
  });
@@ -48271,12 +47208,6 @@ const normalizeFirmwareBinary = (binary) => {
48271
47208
  }
48272
47209
  return normalized.buffer;
48273
47210
  };
48274
- const toArrayBuffer = (binary) => {
48275
- if (binary instanceof ArrayBuffer) {
48276
- return binary;
48277
- }
48278
- return new Uint8Array(binary.buffer, binary.byteOffset, binary.byteLength).slice().buffer;
48279
- };
48280
47211
  class FirmwareUpdateV2 extends BaseMethod {
48281
47212
  constructor() {
48282
47213
  super(...arguments);
@@ -48291,7 +47222,6 @@ class FirmwareUpdateV2 extends BaseMethod {
48291
47222
  };
48292
47223
  }
48293
47224
  init() {
48294
- var _a;
48295
47225
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
48296
47226
  this.requireDeviceMode = [];
48297
47227
  this.useDevicePassphraseState = false;
@@ -48318,28 +47248,6 @@ class FirmwareUpdateV2 extends BaseMethod {
48318
47248
  if ('binary' in payload) {
48319
47249
  this.params = Object.assign(Object.assign({}, this.params), { binary: payload.binary });
48320
47250
  }
48321
- if ('artifact' in payload) {
48322
- const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration);
48323
- const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
48324
- const resourceBindings = [
48325
- ...(payload.resourceArtifact
48326
- ? [{ target: 'resource', artifact: payload.resourceArtifact }]
48327
- : []),
48328
- ...((_a = payload.resourceEntries) !== null && _a !== void 0 ? _a : []).map((entry) => ({
48329
- target: 'resource',
48330
- entryName: entry.entryName,
48331
- artifact: entry.artifact,
48332
- })),
48333
- ];
48334
- assertFirmwareUpdatePreparedPlanBinding({
48335
- preparedPlan: payload.preparedPlan,
48336
- executor: 'v2',
48337
- platform: payload.platform,
48338
- scopeTargets: [target, ...(target === 'firmware' ? ['resource'] : [])],
48339
- bindings: [{ target, artifact: payload.artifact }, ...resourceBindings],
48340
- });
48341
- this.params = Object.assign(Object.assign({}, this.params), { preparedPlan: payload.preparedPlan, artifact: payload.artifact, resourceArtifact: payload.resourceArtifact, resourceEntries: payload.resourceEntries, artifactReader: hostBinding.artifactReader });
48342
- }
48343
47251
  }
48344
47252
  _promptDeviceInBootloaderForWebDevice() {
48345
47253
  return __awaiter(this, void 0, void 0, function* () {
@@ -48479,7 +47387,7 @@ class FirmwareUpdateV2 extends BaseMethod {
48479
47387
  }
48480
47388
  }
48481
47389
  run() {
48482
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
47390
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
48483
47391
  return __awaiter(this, void 0, void 0, function* () {
48484
47392
  const { device, params } = this;
48485
47393
  const { features, commands } = device;
@@ -48487,186 +47395,104 @@ class FirmwareUpdateV2 extends BaseMethod {
48487
47395
  if (device.isProtocolV2()) {
48488
47396
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware update must use firmwareUpdateV4');
48489
47397
  }
48490
- if (params.preparedPlan) {
48491
- assertFirmwareUpdatePreparedPlanDeviceIdentity({
48492
- preparedPlan: params.preparedPlan,
48493
- deviceIdentity: getDeviceUUID(features) || undefined,
48494
- });
48495
- }
48496
47398
  const deviceFirmwareType = device.getCurrentFirmwareType();
48497
47399
  const firmwareType = (_a = params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
48498
47400
  this.checkVersionForCopyTouchResource(features, firmwareType);
48499
- let preparedSource;
48500
- try {
48501
- const acquireFirmwareSource = () => __awaiter(this, void 0, void 0, function* () {
48502
- var _k;
48503
- try {
48504
- if (preparedSource) {
48505
- return preparedSource;
48506
- }
48507
- if (params.binary !== undefined) {
48508
- const binary = normalizeFirmwareBinary(params.binary);
48509
- if (!binary) {
48510
- throw new Error('firmware binary is empty or invalid');
48511
- }
48512
- const source = yield openFirmwareByteSource({
48513
- binary: toArrayBuffer(binary),
48514
- });
48515
- if (!source) {
48516
- throw new Error('firmware binary is empty or invalid');
48517
- }
48518
- preparedSource = source;
48519
- return source;
48520
- }
48521
- if (params.artifact) {
48522
- const source = yield openFirmwareByteSource({
48523
- artifact: params.artifact,
48524
- reader: params.artifactReader,
48525
- });
48526
- if (!source) {
48527
- throw new Error('firmware artifact is not prepared');
48528
- }
48529
- preparedSource = source;
48530
- return source;
48531
- }
48532
- if (!device.features) {
48533
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'no features found for this device');
48534
- }
48535
- if (params.artifactReader ||
48536
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48537
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware must be prepared by the external firmware host', {
48538
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48539
- artifactName: 'firmware',
48540
- });
48541
- }
48542
- this.postTipMessage('DownloadFirmware');
48543
- const firmware = yield getBinary({
48544
- features: device.features,
48545
- version: params.version,
48546
- updateType: params.updateType,
48547
- isUpdateBootloader: params.isUpdateBootloader,
48548
- firmwareType,
48549
- requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
48550
- });
48551
- const binary = normalizeFirmwareBinary(firmware.binary);
48552
- if (!binary) {
48553
- throw new Error('downloaded firmware binary is empty or invalid');
48554
- }
48555
- const source = yield openFirmwareByteSource({
48556
- binary: toArrayBuffer(binary),
48557
- });
48558
- if (!source) {
48559
- throw new Error('downloaded firmware binary is empty or invalid');
47401
+ let preparedBinary;
47402
+ const acquireFirmwareBinary = () => __awaiter(this, void 0, void 0, function* () {
47403
+ var _l;
47404
+ try {
47405
+ if (preparedBinary) {
47406
+ return preparedBinary;
47407
+ }
47408
+ if (params.binary !== undefined) {
47409
+ preparedBinary = normalizeFirmwareBinary(params.binary);
47410
+ if (!preparedBinary) {
47411
+ throw new Error('firmware binary is empty or invalid');
48560
47412
  }
48561
- preparedSource = source;
48562
- this.postTipMessage('DownloadFirmwareSuccess');
48563
- return source;
47413
+ return preparedBinary;
48564
47414
  }
48565
- catch (err) {
48566
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_k = err.message) !== null && _k !== void 0 ? _k : err);
47415
+ if (!device.features) {
47416
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'no features found for this device');
48567
47417
  }
48568
- });
48569
- if (!device.isBootloader() && features) {
48570
- const serialNo = device.getCurrentSerialNo();
48571
- if (this.isEnteredManuallyBoot()) {
48572
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateManuallyEnterBoot);
47418
+ this.postTipMessage('DownloadFirmware');
47419
+ const firmware = yield getBinary({
47420
+ features: device.features,
47421
+ version: params.version,
47422
+ updateType: params.updateType,
47423
+ isUpdateBootloader: params.isUpdateBootloader,
47424
+ firmwareType,
47425
+ requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
47426
+ });
47427
+ preparedBinary = normalizeFirmwareBinary(firmware.binary);
47428
+ if (!preparedBinary) {
47429
+ throw new Error('downloaded firmware binary is empty or invalid');
48573
47430
  }
48574
- yield acquireFirmwareSource();
48575
- if (this.isSupportResourceUpdate(params.updateType)) {
48576
- this.postTipMessage('CheckLatestUiResource');
48577
- const resourceUrl = DataManager.getSysResourcesLatestRelease({
48578
- features,
48579
- forcedUpdateRes: params.forcedUpdateRes,
48580
- firmwareType,
48581
- });
48582
- if (resourceUrl) {
48583
- this.postTipMessage('DownloadLatestUiResource');
48584
- if ((_b = params.resourceEntries) === null || _b === void 0 ? void 0 : _b.length) {
48585
- const sources = [];
48586
- try {
48587
- for (const entry of params.resourceEntries) {
48588
- const resourceName = getFirmwareUpdateResourceName(entry.entryName);
48589
- const source = yield openFirmwareByteSource({
48590
- artifact: entry.artifact,
48591
- reader: params.artifactReader,
48592
- });
48593
- if (!source) {
48594
- throw new Error('Firmware resource entry is not prepared');
48595
- }
48596
- sources.push({ entryName: resourceName, source });
48597
- }
48598
- yield updateResourcesFromSources(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, sources.map(entry => ({
48599
- entryName: entry.entryName,
48600
- source: entry.source,
48601
- })));
48602
- }
48603
- finally {
48604
- yield Promise.all(sources.map(entry => entry.source.close().catch(() => undefined)));
48605
- }
48606
- this.postTipMessage('DownloadLatestUiResourceSuccess');
48607
- }
48608
- else {
48609
- let resourceBinary;
48610
- if (params.resourceArtifact) {
48611
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware resource archive must be materialized into prepared entries', {
48612
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48613
- artifactName: 'resource',
48614
- });
48615
- }
48616
- else {
48617
- if (params.artifactReader ||
48618
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48619
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware resource must be prepared by the external firmware host', {
48620
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48621
- artifactName: 'resource',
48622
- });
48623
- }
48624
- resourceBinary = (yield getSysResourceBinary(resourceUrl)).binary;
48625
- }
48626
- this.postTipMessage('DownloadLatestUiResourceSuccess');
48627
- yield updateResources(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, resourceBinary);
48628
- }
47431
+ this.postTipMessage('DownloadFirmwareSuccess');
47432
+ return preparedBinary;
47433
+ }
47434
+ catch (err) {
47435
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_l = err.message) !== null && _l !== void 0 ? _l : err);
47436
+ }
47437
+ });
47438
+ if (!device.isBootloader() && features) {
47439
+ const serialNo = device.getCurrentSerialNo();
47440
+ if (this.isEnteredManuallyBoot()) {
47441
+ return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateManuallyEnterBoot));
47442
+ }
47443
+ if (this.isSupportResourceUpdate(params.updateType)) {
47444
+ this.postTipMessage('CheckLatestUiResource');
47445
+ const resourceUrl = DataManager.getSysResourcesLatestRelease({
47446
+ features,
47447
+ forcedUpdateRes: params.forcedUpdateRes,
47448
+ firmwareType,
47449
+ });
47450
+ if (resourceUrl) {
47451
+ this.postTipMessage('DownloadLatestUiResource');
47452
+ const resource = yield getSysResourceBinary(resourceUrl);
47453
+ this.postTipMessage('DownloadLatestUiResourceSuccess');
47454
+ if (resource) {
47455
+ yield updateResources(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, resource.binary);
48629
47456
  }
48630
47457
  }
48631
- (_d = (_c = this.device) === null || _c === void 0 ? void 0 : _c.commands) === null || _d === void 0 ? void 0 : _d.checkDisposed();
48632
- try {
48633
- this.postTipMessage('AutoRebootToBootloader');
48634
- const bootRes = yield commands.typedCall('DeviceBackToBoot', 'Success');
48635
- if (bootRes.type === 'CallMethodError') {
48636
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
48637
- }
48638
- this.postTipMessage('GoToBootloaderSuccess');
48639
- this.checkDeviceToBootloader(this.payload.connectId);
48640
- if (DeviceModelToTypes.model_classic.includes(deviceType)) {
48641
- DevicePool.clearDeviceCache(serialNo);
48642
- }
48643
- delete DevicePool.devicesCache[''];
48644
- yield ((_e = this.checkPromise) === null || _e === void 0 ? void 0 : _e.promise);
48645
- this.checkPromise = null;
48646
- (_g = (_f = this.device) === null || _f === void 0 ? void 0 : _f.commands) === null || _g === void 0 ? void 0 : _g.checkDisposed();
48647
- const isTouch = DeviceModelToTypes.model_touch.includes(deviceType);
48648
- yield wait(isTouch ? 3000 : 1500);
47458
+ }
47459
+ (_c = (_b = this.device) === null || _b === void 0 ? void 0 : _b.commands) === null || _c === void 0 ? void 0 : _c.checkDisposed();
47460
+ yield acquireFirmwareBinary();
47461
+ (_e = (_d = this.device) === null || _d === void 0 ? void 0 : _d.commands) === null || _e === void 0 ? void 0 : _e.checkDisposed();
47462
+ try {
47463
+ this.postTipMessage('AutoRebootToBootloader');
47464
+ const bootRes = yield commands.typedCall('DeviceBackToBoot', 'Success');
47465
+ if (bootRes.type === 'CallMethodError') {
47466
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
48649
47467
  }
48650
- catch (e) {
48651
- if (e instanceof hdShared.HardwareError) {
48652
- return Promise.reject(e);
48653
- }
48654
- console.log('auto go to bootloader mode failed: ', e);
48655
- return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure));
47468
+ this.postTipMessage('GoToBootloaderSuccess');
47469
+ this.checkDeviceToBootloader(this.payload.connectId);
47470
+ if (DeviceModelToTypes.model_classic.includes(deviceType)) {
47471
+ DevicePool.clearDeviceCache(serialNo);
48656
47472
  }
47473
+ delete DevicePool.devicesCache[''];
47474
+ yield ((_f = this.checkPromise) === null || _f === void 0 ? void 0 : _f.promise);
47475
+ this.checkPromise = null;
47476
+ (_h = (_g = this.device) === null || _g === void 0 ? void 0 : _g.commands) === null || _h === void 0 ? void 0 : _h.checkDisposed();
47477
+ const isTouch = DeviceModelToTypes.model_touch.includes(deviceType);
47478
+ yield wait(isTouch ? 3000 : 1500);
48657
47479
  }
48658
- const source = yield acquireFirmwareSource();
48659
- (_j = (_h = this.device) === null || _h === void 0 ? void 0 : _h.commands) === null || _j === void 0 ? void 0 : _j.checkDisposed();
48660
- yield this.device.acquire();
48661
- const response = yield uploadFirmwareFromSource(params.updateType, this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, source, true, params.isUpdateBootloader);
48662
- if (this.connectId) {
48663
- DevicePool.clearDeviceCache(this.connectId);
47480
+ catch (e) {
47481
+ if (e instanceof hdShared.HardwareError) {
47482
+ return Promise.reject(e);
47483
+ }
47484
+ console.log('auto go to bootloader mode failed: ', e);
47485
+ return Promise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure));
48664
47486
  }
48665
- return response;
48666
47487
  }
48667
- finally {
48668
- yield (preparedSource === null || preparedSource === void 0 ? void 0 : preparedSource.close().catch(() => undefined));
47488
+ const binary = yield acquireFirmwareBinary();
47489
+ (_k = (_j = this.device) === null || _j === void 0 ? void 0 : _j.commands) === null || _k === void 0 ? void 0 : _k.checkDisposed();
47490
+ yield this.device.acquire();
47491
+ const response = yield uploadFirmware(params.updateType, this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, { payload: binary, rebootOnSuccess: true }, params.isUpdateBootloader);
47492
+ if (this.connectId) {
47493
+ DevicePool.clearDeviceCache(this.connectId);
48669
47494
  }
47495
+ return response;
48670
47496
  });
48671
47497
  }
48672
47498
  }
@@ -48678,10 +47504,8 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48678
47504
  super(...arguments);
48679
47505
  this.checkPromise = null;
48680
47506
  this.isSwitchFirmware = false;
48681
- this.artifactSources = [];
48682
47507
  }
48683
47508
  init() {
48684
- var _a, _b, _c, _d, _e, _f;
48685
47509
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
48686
47510
  this.requireDeviceMode = [];
48687
47511
  this.useDevicePassphraseState = false;
@@ -48699,50 +47523,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48699
47523
  { name: 'firmwareType', type: 'string' },
48700
47524
  { name: 'platform', type: 'string' },
48701
47525
  ]);
48702
- const hostBinding = payload.artifacts || payload.preparedPlan
48703
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
48704
- : undefined;
48705
- if (hostBinding) {
48706
- assertFirmwareUpdatePreparedPlanBinding({
48707
- preparedPlan: payload.preparedPlan,
48708
- executor: 'v3',
48709
- platform: payload.platform,
48710
- scopeTargets: ['bootloader', 'firmware', 'resource', 'ble'],
48711
- bindings: [
48712
- ...(((_a = payload.artifacts) === null || _a === void 0 ? void 0 : _a.bootloader)
48713
- ? [
48714
- {
48715
- target: 'bootloader',
48716
- artifact: payload.artifacts.bootloader,
48717
- },
48718
- ]
48719
- : []),
48720
- ...(((_b = payload.artifacts) === null || _b === void 0 ? void 0 : _b.firmware)
48721
- ? [
48722
- {
48723
- target: 'firmware',
48724
- artifact: payload.artifacts.firmware,
48725
- },
48726
- ]
48727
- : []),
48728
- ...(((_c = payload.artifacts) === null || _c === void 0 ? void 0 : _c.ble)
48729
- ? [
48730
- {
48731
- target: 'ble',
48732
- artifact: payload.artifacts.ble,
48733
- },
48734
- ]
48735
- : []),
48736
- ...((_e = (_d = payload.artifacts) === null || _d === void 0 ? void 0 : _d.resourceEntries) !== null && _e !== void 0 ? _e : []).map((entry) => ({
48737
- target: 'resource',
48738
- entryName: entry.entryName,
48739
- artifact: entry.artifact,
48740
- })),
48741
- ],
48742
- });
48743
- }
48744
47526
  this.params = {
48745
- preparedPlan: payload.preparedPlan,
48746
47527
  bleBinary: payload.bleBinary,
48747
47528
  firmwareBinary: payload.firmwareBinary,
48748
47529
  forcedUpdateRes: payload.forcedUpdateRes,
@@ -48753,8 +47534,6 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48753
47534
  resourceBinary: payload.resourceBinary,
48754
47535
  firmwareType: payload.firmwareType,
48755
47536
  platform: payload.platform,
48756
- artifactReader: (_f = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _f !== void 0 ? _f : payload.artifactReader,
48757
- artifacts: payload.artifacts,
48758
47537
  };
48759
47538
  }
48760
47539
  run() {
@@ -48777,48 +47556,32 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48777
47556
  if (!features) {
48778
47557
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Device features not available');
48779
47558
  }
48780
- if (this.params.preparedPlan) {
48781
- assertFirmwareUpdatePreparedPlanDeviceIdentity({
48782
- preparedPlan: this.params.preparedPlan,
48783
- deviceIdentity: getDeviceUUID(features) || undefined,
48784
- });
48785
- }
48786
47559
  const deviceFirmwareType = device.getCurrentFirmwareType();
48787
47560
  const firmwareType = (_b = this.params.firmwareType) !== null && _b !== void 0 ? _b : deviceFirmwareType;
48788
47561
  this.isSwitchFirmware = firmwareType !== deviceFirmwareType;
48789
47562
  let resourceBinary = null;
48790
- let resourceEntries = [];
48791
- let fwSources = [];
48792
- let bootloaderSource = null;
47563
+ let fwBinaryMap = [];
47564
+ let bootloaderBinary = null;
48793
47565
  try {
48794
47566
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
48795
- const resourceInput = yield this.prepareResourceInput(firmwareType);
48796
- resourceBinary = resourceInput.resourceBinary;
48797
- resourceEntries = resourceInput.resourceEntries;
48798
- fwSources = yield this.prepareFirmwareAndBleSources(firmwareType);
48799
- bootloaderSource = yield this.prepareBootloaderSource(firmwareType);
47567
+ resourceBinary = yield this.prepareResourceBinary(firmwareType);
47568
+ fwBinaryMap = yield this.prepareFirmwareAndBleBinary(firmwareType);
47569
+ bootloaderBinary = yield this.prepareBootloaderBinary(firmwareType);
48800
47570
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
48801
47571
  }
48802
47572
  catch (err) {
48803
- yield this.closeArtifactSources();
48804
47573
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_c = err.message) !== null && _c !== void 0 ? _c : err);
48805
47574
  }
48806
- if (!bootloaderSource && fwSources.length === 0) {
48807
- yield this.closeArtifactSources();
47575
+ if (!bootloaderBinary && fwBinaryMap.length === 0) {
48808
47576
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
48809
47577
  }
48810
- try {
48811
- yield this.enterBootloaderMode();
48812
- return yield this.executeUpdate({
48813
- resourceBinary,
48814
- resourceEntries,
48815
- fwSources,
48816
- bootloaderSource,
48817
- });
48818
- }
48819
- finally {
48820
- yield this.closeArtifactSources();
48821
- }
47578
+ yield this.enterBootloaderMode();
47579
+ const updateResult = yield this.executeUpdate({
47580
+ resourceBinary,
47581
+ fwBinaryMap,
47582
+ bootloaderBinary,
47583
+ });
47584
+ return updateResult;
48822
47585
  });
48823
47586
  }
48824
47587
  validateDeviceAndVersion(deviceType, bootloaderVersion) {
@@ -48832,93 +47595,31 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48832
47595
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'bootloader version needs to be updated');
48833
47596
  }
48834
47597
  }
48835
- openArtifactSource(binary, artifact) {
48836
- return __awaiter(this, void 0, void 0, function* () {
48837
- const source = yield openFirmwareByteSource({
48838
- binary,
48839
- artifact,
48840
- reader: this.params.artifactReader,
48841
- });
48842
- if (source) {
48843
- this.artifactSources.push(source);
48844
- }
48845
- return source;
48846
- });
48847
- }
48848
- closeArtifactSources() {
48849
- return __awaiter(this, void 0, void 0, function* () {
48850
- const sources = this.artifactSources.splice(0);
48851
- yield Promise.all(sources.map(source => source.close().catch(() => undefined)));
48852
- });
48853
- }
48854
- assertSdkDownloadAllowed(artifactName) {
48855
- if (this.params.artifactReader ||
48856
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48857
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${artifactName} must be prepared by the external firmware host`, {
48858
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48859
- artifactName,
48860
- });
48861
- }
48862
- }
48863
- prepareResourceInput(firmwareType) {
48864
- var _a;
47598
+ prepareResourceBinary(firmwareType) {
48865
47599
  return __awaiter(this, void 0, void 0, function* () {
48866
- const preparedEntries = (_a = this.params.artifacts) === null || _a === void 0 ? void 0 : _a.resourceEntries;
48867
- if ((preparedEntries === null || preparedEntries === void 0 ? void 0 : preparedEntries.length) && this.params.resourceBinary) {
48868
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware resource input must not contain both archive binary and prepared entries');
48869
- }
48870
- if (preparedEntries === null || preparedEntries === void 0 ? void 0 : preparedEntries.length) {
48871
- const resourceEntries = [];
48872
- for (const entry of preparedEntries) {
48873
- const resourceName = getFirmwareUpdateResourceName(entry.entryName);
48874
- const source = yield this.openArtifactSource(undefined, entry.artifact);
48875
- if (!source) {
48876
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Firmware resource entry ${entry.entryName} is not prepared`);
48877
- }
48878
- resourceEntries.push({ entryName: resourceName, source });
48879
- }
48880
- return {
48881
- resourceBinary: null,
48882
- resourceEntries,
48883
- };
48884
- }
48885
47600
  if (this.params.resourceBinary) {
48886
- return {
48887
- resourceBinary: this.params.resourceBinary,
48888
- resourceEntries: [],
48889
- };
47601
+ return this.params.resourceBinary;
48890
47602
  }
48891
47603
  const { features } = this.device;
48892
- if (!features) {
48893
- return {
48894
- resourceBinary: null,
48895
- resourceEntries: [],
48896
- };
48897
- }
47604
+ if (!features)
47605
+ return null;
48898
47606
  const resourceUrl = DataManager.getSysResourcesLatestRelease({
48899
47607
  features,
48900
47608
  forcedUpdateRes: this.params.forcedUpdateRes,
48901
47609
  firmwareType,
48902
47610
  });
48903
47611
  if (resourceUrl) {
48904
- this.assertSdkDownloadAllowed('resource');
48905
- return {
48906
- resourceBinary: (yield getSysResourceBinary(resourceUrl)).binary,
48907
- resourceEntries: [],
48908
- };
47612
+ const resource = (yield getSysResourceBinary(resourceUrl)).binary;
47613
+ return resource;
48909
47614
  }
48910
47615
  Log$6.warn('No resource url found');
48911
- return {
48912
- resourceBinary: null,
48913
- resourceEntries: [],
48914
- };
47616
+ return null;
48915
47617
  });
48916
47618
  }
48917
- prepareBootloaderSource(firmwareType) {
48918
- var _a, _b;
47619
+ prepareBootloaderBinary(firmwareType) {
48919
47620
  return __awaiter(this, void 0, void 0, function* () {
48920
- if (this.params.bootloaderBinary || ((_a = this.params.artifacts) === null || _a === void 0 ? void 0 : _a.bootloader)) {
48921
- return this.openArtifactSource(this.params.bootloaderBinary, (_b = this.params.artifacts) === null || _b === void 0 ? void 0 : _b.bootloader);
47621
+ if (this.params.bootloaderBinary) {
47622
+ return this.params.bootloaderBinary;
48922
47623
  }
48923
47624
  const { features } = this.device;
48924
47625
  if (!features)
@@ -48926,32 +47627,25 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48926
47627
  if (this.params.bootloaderVersion) {
48927
47628
  const bootResourceUrl = DataManager.getBootloaderResource(features, firmwareType);
48928
47629
  if (bootResourceUrl) {
48929
- this.assertSdkDownloadAllowed('bootloader');
48930
47630
  const bootBinary = (yield getSysResourceBinary(bootResourceUrl)).binary;
48931
- return this.openArtifactSource(bootBinary, undefined);
47631
+ return bootBinary;
48932
47632
  }
48933
47633
  }
48934
47634
  return null;
48935
47635
  });
48936
47636
  }
48937
- prepareFirmwareAndBleSources(firmwareType) {
48938
- var _a, _b, _c, _d;
47637
+ prepareFirmwareAndBleBinary(firmwareType) {
48939
47638
  return __awaiter(this, void 0, void 0, function* () {
48940
- const fwSources = [];
48941
- if (this.params.firmwareBinary || ((_a = this.params.artifacts) === null || _a === void 0 ? void 0 : _a.firmware)) {
48942
- const source = yield this.openArtifactSource(this.params.firmwareBinary, (_b = this.params.artifacts) === null || _b === void 0 ? void 0 : _b.firmware);
48943
- if (!source) {
48944
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware artifact is not prepared');
48945
- }
48946
- fwSources.push({
47639
+ const fwBinaryMap = [];
47640
+ if (this.params.firmwareBinary) {
47641
+ fwBinaryMap.push({
48947
47642
  fileName: 'firmware.bin',
48948
- source,
47643
+ binary: this.params.firmwareBinary,
48949
47644
  });
48950
47645
  }
48951
47646
  else if (this.params.firmwareVersion) {
48952
47647
  const { features } = this.device;
48953
47648
  if (features) {
48954
- this.assertSdkDownloadAllowed('firmware');
48955
47649
  const firmwareBinary = (yield getBinary({
48956
47650
  features,
48957
47651
  version: this.params.firmwareVersion,
@@ -48959,64 +47653,48 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48959
47653
  isUpdateBootloader: false,
48960
47654
  firmwareType,
48961
47655
  })).binary;
48962
- const source = yield this.openArtifactSource(firmwareBinary, undefined);
48963
- if (!source) {
48964
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware binary is not prepared');
48965
- }
48966
- fwSources.push({
47656
+ fwBinaryMap.push({
48967
47657
  fileName: 'firmware.bin',
48968
- source,
47658
+ binary: firmwareBinary,
48969
47659
  });
48970
47660
  }
48971
47661
  }
48972
- if (this.params.bleBinary || ((_c = this.params.artifacts) === null || _c === void 0 ? void 0 : _c.ble)) {
48973
- const source = yield this.openArtifactSource(this.params.bleBinary, (_d = this.params.artifacts) === null || _d === void 0 ? void 0 : _d.ble);
48974
- if (!source) {
48975
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'BLE artifact is not prepared');
48976
- }
48977
- fwSources.push({
47662
+ if (this.params.bleBinary) {
47663
+ fwBinaryMap.push({
48978
47664
  fileName: 'ble-firmware.bin',
48979
- source,
47665
+ binary: this.params.bleBinary,
48980
47666
  });
48981
47667
  }
48982
47668
  else if (this.params.bleVersion) {
48983
47669
  const { features } = this.device;
48984
47670
  if (features) {
48985
- this.assertSdkDownloadAllowed('ble');
48986
47671
  const bleBinary = yield getBinary({
48987
47672
  features,
48988
47673
  version: this.params.bleVersion,
48989
47674
  updateType: 'ble',
48990
47675
  firmwareType,
48991
47676
  });
48992
- const source = yield this.openArtifactSource(bleBinary.binary, undefined);
48993
- if (!source) {
48994
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'BLE binary is not prepared');
48995
- }
48996
- fwSources.push({
47677
+ fwBinaryMap.push({
48997
47678
  fileName: 'ble-firmware.bin',
48998
- source,
47679
+ binary: bleBinary.binary,
48999
47680
  });
49000
47681
  }
49001
47682
  }
49002
- return fwSources;
47683
+ return fwBinaryMap;
49003
47684
  });
49004
47685
  }
49005
- executeUpdate({ resourceBinary, resourceEntries, fwSources, bootloaderSource, }) {
47686
+ executeUpdate({ resourceBinary, fwBinaryMap, bootloaderBinary, }) {
49006
47687
  return __awaiter(this, void 0, void 0, function* () {
49007
47688
  let totalSize = 0;
49008
47689
  let processedSize = 0;
49009
47690
  if (resourceBinary) {
49010
47691
  totalSize += resourceBinary.byteLength;
49011
47692
  }
49012
- for (const entry of resourceEntries) {
49013
- totalSize += entry.source.size;
47693
+ for (const fwbinary of fwBinaryMap) {
47694
+ totalSize += fwbinary.binary.byteLength;
49014
47695
  }
49015
- for (const firmware of fwSources) {
49016
- totalSize += firmware.source.size;
49017
- }
49018
- if (bootloaderSource) {
49019
- totalSize += bootloaderSource.size;
47696
+ if (bootloaderBinary) {
47697
+ totalSize += bootloaderBinary.byteLength;
49020
47698
  }
49021
47699
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
49022
47700
  if (resourceBinary) {
@@ -49035,28 +47713,20 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
49035
47713
  }
49036
47714
  }
49037
47715
  }
49038
- for (const entry of resourceEntries) {
49039
- processedSize = yield this.emmcCommonUpdateProcessFromSource({
49040
- source: entry.source,
49041
- filePath: `0:res/${entry.entryName}`,
49042
- processedSize,
49043
- totalSize,
49044
- });
49045
- }
49046
- if (bootloaderSource) {
49047
- processedSize = yield this.emmcCommonUpdateProcessFromSource({
49048
- source: bootloaderSource,
47716
+ if (bootloaderBinary) {
47717
+ processedSize = yield this.emmcCommonUpdateProcess({
47718
+ payload: bootloaderBinary,
49049
47719
  filePath: `0:boot/bootloader.bin`,
49050
47720
  processedSize,
49051
47721
  totalSize,
49052
47722
  });
49053
47723
  }
49054
47724
  yield this.createUpdatesFolderIfNotExists(`0:updates/`);
49055
- for (const firmware of fwSources) {
49056
- if (firmware) {
49057
- processedSize = yield this.emmcCommonUpdateProcessFromSource({
49058
- source: firmware.source,
49059
- filePath: `0:updates/${firmware.fileName}`,
47725
+ for (const fwbinary of fwBinaryMap) {
47726
+ if (fwbinary) {
47727
+ processedSize = yield this.emmcCommonUpdateProcess({
47728
+ payload: fwbinary.binary,
47729
+ filePath: `0:updates/${fwbinary.fileName}`,
49060
47730
  processedSize,
49061
47731
  totalSize,
49062
47732
  });
@@ -49401,6 +48071,10 @@ const getProtocolV2DeviceTransferProgress = (bytesBeforeChunk, bytesAfterChunk,
49401
48071
  }
49402
48072
  return Math.min(Math.max(Math.ceil((bytesAfterChunk / totalBytes) * 100), 1), 99);
49403
48073
  };
48074
+ const formatProtocolV2TransferSpeed = (bytes, elapsedMs) => {
48075
+ const safeElapsedMs = Math.max(elapsedMs, 1);
48076
+ return (bytes / 1024 / (safeElapsedMs / 1000)).toFixed(2);
48077
+ };
49404
48078
  const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
49405
48079
  BOOTLOADER: {
49406
48080
  fileName: 'bootloader.bin',
@@ -49582,21 +48256,14 @@ const parseProtocolV2OkppHeader = (bytes) => {
49582
48256
  };
49583
48257
  const assertProtocolV2ReconnectIdentity = (expectedSerialNumber, actualSerialNumber) => {
49584
48258
  if (!expectedSerialNumber || !actualSerialNumber) {
49585
- return;
48259
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, 'Protocol V2 reconnect physical identity is unavailable');
49586
48260
  }
49587
48261
  if (actualSerialNumber !== expectedSerialNumber) {
49588
48262
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Protocol V2 reconnect physical identity mismatch: expected ${expectedSerialNumber}, received ${actualSerialNumber}`);
49589
48263
  }
49590
48264
  };
49591
48265
  class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49592
- constructor() {
49593
- super(...arguments);
49594
- this.protocolV2PreparedSources = [];
49595
- this.protocolV2ExecutionInLoader = false;
49596
- this.protocolV2CompletedTargetVersions = new Map();
49597
- }
49598
48266
  init() {
49599
- var _a, _b, _c;
49600
48267
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
49601
48268
  this.requireDeviceMode = [];
49602
48269
  this.unlockPolicy = 'unlock-before-run';
@@ -49630,51 +48297,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49630
48297
  { name: 'firmwareType', type: 'string' },
49631
48298
  { name: 'targetsToUpdate', type: 'array', allowEmpty: true },
49632
48299
  { name: 'platform', type: 'string' },
49633
- { name: 'expectedDeviceId', type: 'string' },
49634
48300
  { name: 'resourceBundleFiles', type: 'array', allowEmpty: true },
49635
48301
  ]);
49636
- if (payload.expectedDeviceId !== undefined &&
49637
- (payload.expectedDeviceId.length === 0 || payload.expectedDeviceId.length > 160)) {
49638
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 expected device identity is invalid');
49639
- }
49640
- const hostBinding = payload.preparedPlan || payload.componentArtifacts || payload.resourceBundleArtifacts
49641
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
49642
- : undefined;
49643
- if (hostBinding) {
49644
- assertFirmwareUpdatePreparedPlanBinding({
49645
- preparedPlan: payload.preparedPlan,
49646
- executor: 'v4',
49647
- platform: payload.platform,
49648
- scopeTargets: [
49649
- 'boot',
49650
- 'app_v1',
49651
- 'app_v2',
49652
- 'coprocessor',
49653
- 'resource',
49654
- 'se01',
49655
- 'se02',
49656
- 'se03',
49657
- 'se04',
49658
- ],
49659
- bindings: [
49660
- ...Object.entries((_a = payload.componentArtifacts) !== null && _a !== void 0 ? _a : {}).flatMap(([target, artifact]) => artifact
49661
- ? [
49662
- {
49663
- target: target,
49664
- artifact,
49665
- },
49666
- ]
49667
- : []),
49668
- ...((_b = payload.resourceBundleArtifacts) !== null && _b !== void 0 ? _b : []).map((entry) => ({
49669
- target: 'resource',
49670
- logicalName: entry.name,
49671
- artifact: entry.artifact,
49672
- })),
49673
- ],
49674
- });
49675
- }
49676
48302
  this.params = {
49677
- preparedPlan: payload.preparedPlan,
49678
48303
  chunkSize: payload.chunkSize,
49679
48304
  forcedUpdateRes: payload.forcedUpdateRes,
49680
48305
  bootloaderBinary: payload.bootloaderBinary,
@@ -49689,21 +48314,21 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49689
48314
  resourceBundleFiles: payload.resourceBundleFiles,
49690
48315
  firmwareType: payload.firmwareType,
49691
48316
  targetsToUpdate: payload.targetsToUpdate,
49692
- expectedTargetVersions: payload.expectedTargetVersions,
49693
48317
  platform: payload.platform,
49694
- expectedDeviceId: payload.expectedDeviceId,
49695
- artifactReader: (_c = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _c !== void 0 ? _c : payload.artifactReader,
49696
- componentArtifacts: payload.componentArtifacts,
49697
- resourceBundleArtifacts: payload.resourceBundleArtifacts,
49698
48318
  };
49699
48319
  }
49700
- getProtocolV2FirmwareChunkSize() {
48320
+ getProtocolV2FirmwareChunkSize(direction = 'write') {
49701
48321
  var _a, _b;
49702
48322
  const payloadChunkSize = Number((_a = this.params) === null || _a === void 0 ? void 0 : _a.chunkSize);
49703
48323
  const env = DataManager.getSettings('env');
49704
- const maxChunkSize = ((_b = this.params) === null || _b === void 0 ? void 0 : _b.platform) === 'native' || (env && DataManager.isBleConnect(env))
49705
- ? hdTransport.PROTOCOL_V2_BLE_FILE_CHUNK_SIZE
49706
- : hdTransport.PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
48324
+ const isBle = ((_b = this.params) === null || _b === void 0 ? void 0 : _b.platform) === 'native' || (env && DataManager.isBleConnect(env));
48325
+ let maxChunkSize = hdTransport.PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
48326
+ if (isBle) {
48327
+ maxChunkSize =
48328
+ direction === 'read'
48329
+ ? hdTransport.PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE
48330
+ : hdTransport.PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
48331
+ }
49707
48332
  if (!Number.isFinite(payloadChunkSize) || payloadChunkSize <= 0) {
49708
48333
  return maxChunkSize;
49709
48334
  }
@@ -49719,17 +48344,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49719
48344
  });
49720
48345
  }
49721
48346
  runProtocolV2() {
49722
- var _a, _b, _c;
48347
+ var _a, _b;
49723
48348
  return __awaiter(this, void 0, void 0, function* () {
49724
48349
  yield this.captureProtocolV2PhysicalIdentity();
49725
48350
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
49726
48351
  const deviceFirmwareType = getFirmwareType(deviceFeatures);
49727
48352
  const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
49728
- this.validateExpectedTargetVersions();
49729
- if ((this.params.componentArtifacts && Object.keys(this.params.componentArtifacts).length > 0) ||
49730
- ((_b = this.params.resourceBundleArtifacts) === null || _b === void 0 ? void 0 : _b.length)) {
49731
- return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
49732
- }
49733
48353
  let fwBinaryMap = [];
49734
48354
  let bootloaderBinary = null;
49735
48355
  let installItems;
@@ -49739,245 +48359,33 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49739
48359
  fwBinaryMap = this.collectExplicitTargetBinaries();
49740
48360
  bootloaderBinary = this.prepareBootloaderBinary();
49741
48361
  if (!this.hasExplicitProtocolV2Payload(fwBinaryMap)) {
49742
- if (this.params.artifactReader ||
49743
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
49744
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware artifacts must be prepared by the external firmware host', {
49745
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49746
- });
49747
- }
49748
48362
  const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures);
49749
48363
  bootloaderBinary = remoteBinaries.bootloaderBinary;
49750
48364
  fwBinaryMap = remoteBinaries.fwBinaryMap;
49751
48365
  installItems = remoteBinaries.installItems;
49752
48366
  }
49753
- const resourceDescriptors = this.prepareProtocolV2ResourceBundles(firmwareType, deviceFeatures);
49754
- resourceBundles = (resourceDescriptors === null || resourceDescriptors === void 0 ? void 0 : resourceDescriptors.length)
49755
- ? yield this.materializeProtocolV2ResourceBundles(resourceDescriptors)
49756
- : undefined;
48367
+ resourceBundles = this.prepareProtocolV2ResourceBundles(firmwareType, deviceFeatures);
48368
+ if (resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) {
48369
+ resourceBundles = yield this.prefetchProtocolV2ResourceBundles(resourceBundles);
48370
+ }
49757
48371
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
49758
48372
  }
49759
48373
  catch (err) {
49760
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_c = err.message) !== null && _c !== void 0 ? _c : err);
48374
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_b = err.message) !== null && _b !== void 0 ? _b : err);
49761
48375
  }
49762
48376
  if (!bootloaderBinary && fwBinaryMap.length === 0 && !(resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length)) {
49763
48377
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
49764
48378
  }
49765
- return this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
48379
+ yield this.enterProtocolV2BootloaderMode();
48380
+ yield this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
49766
48381
  bootloaderBinary }, (installItems ? { installItems } : undefined)), ((resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) ? { resourceBundles } : undefined)));
48382
+ yield this.exitProtocolV2BootloaderToNormal();
48383
+ const versions = yield this.waitForProtocolV2FinalFeatures();
48384
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdateCompleted);
48385
+ DevicePool.resetState();
48386
+ return versions;
49767
48387
  });
49768
48388
  }
49769
- openProtocolV2PreparedSource(artifact) {
49770
- return __awaiter(this, void 0, void 0, function* () {
49771
- const source = yield openFirmwareByteSource({
49772
- artifact,
49773
- reader: this.params.artifactReader,
49774
- });
49775
- if (!source) {
49776
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Firmware artifact ${artifact.artifactRef} is not prepared`, {
49777
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49778
- });
49779
- }
49780
- this.protocolV2PreparedSources.push(source);
49781
- return source;
49782
- });
49783
- }
49784
- openProtocolV2MemorySource(binary) {
49785
- return __awaiter(this, void 0, void 0, function* () {
49786
- const source = yield openFirmwareByteSource({ binary });
49787
- if (!source) {
49788
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware binary is empty');
49789
- }
49790
- this.protocolV2PreparedSources.push(source);
49791
- return source;
49792
- });
49793
- }
49794
- closeProtocolV2PreparedSources() {
49795
- return __awaiter(this, void 0, void 0, function* () {
49796
- const sources = this.protocolV2PreparedSources.splice(0);
49797
- yield Promise.all(sources.map(source => source.close().catch(() => undefined)));
49798
- });
49799
- }
49800
- prepareProtocolV2InstallSources(firmwareType, features) {
49801
- var _a, _b;
49802
- return __awaiter(this, void 0, void 0, function* () {
49803
- const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
49804
- if (!release) {
49805
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware release is unavailable');
49806
- }
49807
- const componentArtifacts = (_a = this.params.componentArtifacts) !== null && _a !== void 0 ? _a : {};
49808
- const requestedTargets = new Set((_b = this.params.targetsToUpdate) !== null && _b !== void 0 ? _b : Object.keys(componentArtifacts));
49809
- const installSources = [];
49810
- const preparedTargets = new Set();
49811
- for (const [key, component] of this.getRemoteComponentEntries(release)) {
49812
- const target = this.getRemoteComponentTarget(key, component);
49813
- const updateTarget = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId);
49814
- if (updateTarget && updateTarget !== 'resource' && requestedTargets.has(updateTarget)) {
49815
- const artifact = componentArtifacts[updateTarget];
49816
- if (!artifact) {
49817
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 ${updateTarget} artifact is not prepared`, {
49818
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49819
- artifactName: updateTarget,
49820
- });
49821
- }
49822
- installSources.push(Object.assign(Object.assign({}, target), { source: yield this.openProtocolV2PreparedSource(artifact) }));
49823
- preparedTargets.add(updateTarget);
49824
- }
49825
- }
49826
- const unknownTarget = Array.from(requestedTargets).find(target => target !== 'resource' && !preparedTargets.has(target));
49827
- if (unknownTarget) {
49828
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain requested target ${unknownTarget}`);
49829
- }
49830
- return installSources;
49831
- });
49832
- }
49833
- prepareProtocolV2ResourceSources(firmwareType, features) {
49834
- var _a, _b, _c;
49835
- return __awaiter(this, void 0, void 0, function* () {
49836
- const preparedArtifacts = (_a = this.params.resourceBundleArtifacts) !== null && _a !== void 0 ? _a : [];
49837
- const resourceRequested = ((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource')) || preparedArtifacts.length > 0;
49838
- if (!resourceRequested) {
49839
- return [];
49840
- }
49841
- const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
49842
- const descriptors = (_c = release === null || release === void 0 ? void 0 : release.resourceBundles) !== null && _c !== void 0 ? _c : [];
49843
- const artifactByName = new Map(preparedArtifacts.map(item => [item.name, item.artifact]));
49844
- const sources = [];
49845
- for (const descriptor of descriptors) {
49846
- const artifact = artifactByName.get(descriptor.name);
49847
- if (!artifact) {
49848
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource bundle ${descriptor.name} is not prepared`, {
49849
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49850
- artifactName: descriptor.name,
49851
- });
49852
- }
49853
- const devicePath = validateProtocolV2FilesystemPath(descriptor.devicePath, 'resourceBundles[].devicePath');
49854
- sources.push({
49855
- name: descriptor.name,
49856
- source: yield this.openProtocolV2PreparedSource(artifact),
49857
- devicePath,
49858
- version: descriptor.version,
49859
- payloadHash: descriptor.payloadHash,
49860
- headerHash: descriptor.headerHash,
49861
- });
49862
- artifactByName.delete(descriptor.name);
49863
- }
49864
- if (artifactByName.size > 0) {
49865
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain resource bundle ${artifactByName.keys().next().value}`);
49866
- }
49867
- return sources;
49868
- });
49869
- }
49870
- runProtocolV2PreparedArtifacts(features, firmwareType) {
49871
- return __awaiter(this, void 0, void 0, function* () {
49872
- try {
49873
- this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
49874
- const installSources = yield this.prepareProtocolV2InstallSources(firmwareType, features);
49875
- const resourceSources = yield this.prepareProtocolV2ResourceSources(firmwareType, features);
49876
- if (installSources.length === 0 && resourceSources.length === 0) {
49877
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
49878
- }
49879
- this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
49880
- return yield this.executeProtocolV2SourceUpdate({
49881
- installSources,
49882
- resourceSources,
49883
- });
49884
- }
49885
- finally {
49886
- yield this.closeProtocolV2PreparedSources();
49887
- }
49888
- });
49889
- }
49890
- validateExpectedTargetVersions() {
49891
- const expected = this.params.expectedTargetVersions;
49892
- if (expected === undefined)
49893
- return;
49894
- if (typeof expected !== 'object' || expected === null || Array.isArray(expected)) {
49895
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 expected target versions are invalid');
49896
- }
49897
- for (const [target, version] of Object.entries(expected)) {
49898
- if (!Array.from(PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.values()).includes(target) ||
49899
- typeof version !== 'string' ||
49900
- !/^\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?$/u.test(version) ||
49901
- version.length > 64) {
49902
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 expected target version is invalid');
49903
- }
49904
- }
49905
- }
49906
- getExpectedProtocolV2TargetVersion(targetId) {
49907
- var _a, _b;
49908
- const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(targetId);
49909
- const version = target ? (_b = (_a = this.params) === null || _a === void 0 ? void 0 : _a.expectedTargetVersions) === null || _b === void 0 ? void 0 : _b[target] : undefined;
49910
- if (!version)
49911
- return undefined;
49912
- const parts = version.split(/[+-]/u, 1)[0].split('.').map(Number);
49913
- if (parts.length !== 3 ||
49914
- parts.some(part => !Number.isSafeInteger(part) || part < 0 || part > 0xff)) {
49915
- return undefined;
49916
- }
49917
- return parts[0] * 0x10000 + parts[1] * 0x100 + parts[2];
49918
- }
49919
- assertExpectedProtocolV2Versions(targets) {
49920
- var _a, _b, _c, _d, _e, _f;
49921
- const expected = (_a = this.params) === null || _a === void 0 ? void 0 : _a.expectedTargetVersions;
49922
- if (!expected)
49923
- return;
49924
- const features = this.protocolV2LatestFinalFeatures;
49925
- const requestedTargets = this.getProtocolV2RequestedTargets();
49926
- const applicationTargets = requestedTargets.filter(target => target === 'app_v1' || target === 'app_v2');
49927
- const visibleVersions = {
49928
- boot: features ? getDeviceBootloaderVersion(features).join('.') : undefined,
49929
- coprocessor: features ? getDeviceBLEFirmwareVersion(features).join('.') : undefined,
49930
- se01: (_b = features === null || features === void 0 ? void 0 : features.se01Version) !== null && _b !== void 0 ? _b : undefined,
49931
- se02: (_c = features === null || features === void 0 ? void 0 : features.se02Version) !== null && _c !== void 0 ? _c : undefined,
49932
- se03: (_d = features === null || features === void 0 ? void 0 : features.se03Version) !== null && _d !== void 0 ? _d : undefined,
49933
- se04: (_e = features === null || features === void 0 ? void 0 : features.se04Version) !== null && _e !== void 0 ? _e : undefined,
49934
- };
49935
- if (features && applicationTargets.length === 1) {
49936
- visibleVersions[applicationTargets[0]] = getDeviceFirmwareVersion(features).join('.');
49937
- }
49938
- const expectedEntries = Object.entries(expected).filter(([target]) => !targets || targets.includes(target));
49939
- for (const [target, expectedVersion] of expectedEntries) {
49940
- const targetId = (_f = Array.from(PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.entries()).find(([, mappedTarget]) => mappedTarget === target)) === null || _f === void 0 ? void 0 : _f[0];
49941
- const statusVersion = targetId === undefined ? undefined : this.protocolV2CompletedTargetVersions.get(targetId);
49942
- const observedVersion = statusVersion === undefined
49943
- ? visibleVersions[target]
49944
- : `${Math.floor(statusVersion / 0x10000) % 0x100}.${Math.floor(statusVersion / 0x100) % 0x100}.${statusVersion % 0x100}`;
49945
- if (!observedVersion) {
49946
- Log$5.warn(`Protocol V2 target ${target} has no observable final version; skipping version comparison`);
49947
- }
49948
- else if (observedVersion !== expectedVersion) {
49949
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareVerificationFailed, `Protocol V2 target ${target} reached ${observedVersion}, expected ${expectedVersion}`);
49950
- }
49951
- }
49952
- }
49953
- getProtocolV2RequestedTargets() {
49954
- var _a, _b, _c, _d;
49955
- if ((_a = this.params.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.length) {
49956
- return [...new Set(this.params.targetsToUpdate)];
49957
- }
49958
- const targets = new Set();
49959
- Object.keys((_b = this.params.componentArtifacts) !== null && _b !== void 0 ? _b : {}).forEach(target => targets.add(target));
49960
- if (((_c = this.params.resourceBundleArtifacts) === null || _c === void 0 ? void 0 : _c.length) || ((_d = this.params.resourceBundleFiles) === null || _d === void 0 ? void 0 : _d.length)) {
49961
- targets.add('resource');
49962
- }
49963
- if (this.params.bootloaderBinary)
49964
- targets.add('boot');
49965
- if (this.params.applicationP1Binary)
49966
- targets.add('app_v1');
49967
- if (this.params.applicationP2Binary)
49968
- targets.add('app_v2');
49969
- if (this.params.coprocessorBinary)
49970
- targets.add('coprocessor');
49971
- if (this.params.se01Binary)
49972
- targets.add('se01');
49973
- if (this.params.se02Binary)
49974
- targets.add('se02');
49975
- if (this.params.se03Binary)
49976
- targets.add('se03');
49977
- if (this.params.se04Binary)
49978
- targets.add('se04');
49979
- return Array.from(targets);
49980
- }
49981
48389
  getProtocolV2DeviceFeatures() {
49982
48390
  return __awaiter(this, void 0, void 0, function* () {
49983
48391
  if (this.device.features) {
@@ -50008,19 +48416,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50008
48416
  });
50009
48417
  }
50010
48418
  captureProtocolV2PhysicalIdentity() {
50011
- var _a, _b;
50012
48419
  return __awaiter(this, void 0, void 0, function* () {
50013
48420
  const deviceInfo = yield this.requestProtocolV2PhysicalIdentity();
50014
48421
  const serialNumber = this.getProtocolV2SerialNumber(deviceInfo);
50015
- if ((_a = this.params) === null || _a === void 0 ? void 0 : _a.preparedPlan) {
50016
- assertFirmwareUpdatePreparedPlanDeviceIdentity({
50017
- preparedPlan: this.params.preparedPlan,
50018
- deviceIdentity: serialNumber,
50019
- });
50020
- }
50021
- else {
50022
- assertProtocolV2ReconnectIdentity((_b = this.params) === null || _b === void 0 ? void 0 : _b.expectedDeviceId, serialNumber);
50023
- }
48422
+ assertProtocolV2ReconnectIdentity(serialNumber, serialNumber);
50024
48423
  this.protocolV2ExpectedSerialNumber = serialNumber;
50025
48424
  });
50026
48425
  }
@@ -50104,7 +48503,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50104
48503
  fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE) {
50105
48504
  return null;
50106
48505
  }
50107
- const chunkSize = this.getProtocolV2FirmwareChunkSize();
48506
+ const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
50108
48507
  const chunks = [];
50109
48508
  let offset = 0;
50110
48509
  while (offset < PROTOCOL_V2_OKPP_HEADER_SIZE) {
@@ -50221,31 +48620,71 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50221
48620
  headerHash: bundle.headerHash,
50222
48621
  }));
50223
48622
  }
50224
- materializeProtocolV2ResourceBundles(bundles) {
48623
+ prefetchProtocolV2ResourceBundles(bundles) {
50225
48624
  return __awaiter(this, void 0, void 0, function* () {
48625
+ const prefetched = [];
50226
48626
  for (const bundle of bundles) {
50227
- if (bundle.binary.byteLength === 0 && bundle.url) {
50228
- if (this.params.artifactReader ||
50229
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
50230
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Firmware resource bundle ${bundle.name} is not prepared`, {
50231
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
50232
- artifactName: bundle.name,
50233
- });
48627
+ let { binary } = bundle;
48628
+ if (binary.byteLength === 0) {
48629
+ if (!bundle.url) {
48630
+ throw new Error(`Missing Protocol V2 RESC bundle binary: ${bundle.name}`);
50234
48631
  }
50235
- Log$5.log(`[FirmwareUpdateV4] preloading RESC bundle ${bundle.name}`);
50236
- bundle.binary = (yield getSysResourceBinary(bundle.url)).binary;
48632
+ Log$5.log(`[FirmwareUpdateV4] downloading remote RESC bundle ${bundle.name}`);
48633
+ ({ binary } = yield getSysResourceBinary(bundle.url));
50237
48634
  }
50238
- if (bundle.binary.byteLength === 0) {
50239
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, `Protocol V2 RESC bundle is empty: ${bundle.name}`);
48635
+ if (binary.byteLength === 0) {
48636
+ throw new Error(`Protocol V2 RESC bundle is empty: ${bundle.name}`);
48637
+ }
48638
+ prefetched.push(Object.assign(Object.assign({}, bundle), { binary }));
48639
+ }
48640
+ return prefetched;
48641
+ });
48642
+ }
48643
+ syncProtocolV2ResourceBundles(bundles, firmwareSize) {
48644
+ return __awaiter(this, void 0, void 0, function* () {
48645
+ const transferStartTime = Date.now();
48646
+ const transferTransport = this.getProtocolV2FirmwareTransferTransport();
48647
+ const isRemoteMode = bundles.some(bundle => !!bundle.url);
48648
+ let bundlesToSync = bundles;
48649
+ if (isRemoteMode) {
48650
+ const filtered = [];
48651
+ for (const bundle of bundles) {
48652
+ const upToDate = yield this.isProtocolV2ResourceBundleUpToDate(bundle);
48653
+ if (upToDate) {
48654
+ Log$5.log(`[FirmwareUpdateV4] skip RESC bundle ${bundle.name}; already up to date`);
48655
+ }
48656
+ else {
48657
+ filtered.push(bundle);
48658
+ }
50240
48659
  }
48660
+ bundlesToSync = filtered;
48661
+ }
48662
+ if (bundlesToSync.length === 0) {
48663
+ Log$5.log('[FirmwareUpdateV4] all RESC bundles up to date, nothing to sync');
48664
+ return { processedSize: 0, totalSize: firmwareSize };
48665
+ }
48666
+ let totalSize = 0;
48667
+ for (const b of bundlesToSync)
48668
+ totalSize += b.binary.byteLength;
48669
+ const transferTotalSize = totalSize + firmwareSize;
48670
+ let processedSize = 0;
48671
+ for (const bundle of bundlesToSync) {
48672
+ Log$5.log(`[FirmwareUpdateV4] syncing RESC bundle ${bundle.name} -> ${bundle.devicePath} bytes=${bundle.binary.byteLength}`);
48673
+ processedSize = yield this.protocolV2CommonUpdateProcess({
48674
+ payload: bundle.binary,
48675
+ filePath: bundle.devicePath,
48676
+ processedSize,
48677
+ totalSize: transferTotalSize,
48678
+ });
50241
48679
  }
50242
- return bundles;
48680
+ const elapsedMs = Date.now() - transferStartTime;
48681
+ Log$5.log(`[FirmwareUpdateV4] RESC bundle sync finished transport=${transferTransport} bytes=${totalSize} elapsed=${(elapsedMs / 1000).toFixed(2)}s speed=${formatProtocolV2TransferSpeed(totalSize, elapsedMs)} KB/s`);
48682
+ return { processedSize, totalSize: transferTotalSize };
50243
48683
  });
50244
48684
  }
50245
48685
  isProtocolV2ResourceBundleUpToDate(bundle) {
50246
- var _a;
50247
48686
  return __awaiter(this, void 0, void 0, function* () {
50248
- if ((_a = this.params) === null || _a === void 0 ? void 0 : _a.forcedUpdateRes)
48687
+ if (this.params.forcedUpdateRes)
50249
48688
  return false;
50250
48689
  if (!bundle.version && !bundle.payloadHash)
50251
48690
  return false;
@@ -50288,7 +48727,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50288
48727
  return __awaiter(this, void 0, void 0, function* () {
50289
48728
  if (this.isProtocolV2BootloaderMode() || ((_a = this.device.features) === null || _a === void 0 ? void 0 : _a.mode) === 'romloader') {
50290
48729
  Log$5.debug('Protocol V2 device is already in loader mode, skip reboot to bootloader');
50291
- this.protocolV2ExecutionInLoader = true;
50292
48730
  return false;
50293
48731
  }
50294
48732
  try {
@@ -50297,7 +48735,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50297
48735
  this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
50298
48736
  yield hdShared.wait(1000);
50299
48737
  yield this.waitForProtocolV2BootloaderMode();
50300
- this.protocolV2ExecutionInLoader = true;
50301
48738
  return true;
50302
48739
  }
50303
48740
  catch (error) {
@@ -50357,197 +48794,73 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50357
48794
  push(this.params.se04Binary, 'se04.bin', ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04);
50358
48795
  return entries;
50359
48796
  }
50360
- buildProtocolV2ExecutionPhases({ installSources, resourceSources, }) {
50361
- const phases = [];
50362
- if (resourceSources.length > 0) {
50363
- phases.push({
50364
- kind: 'resource-sync',
50365
- installSources: [],
50366
- resourceSources,
50367
- });
50368
- }
50369
- const bootloaderSources = installSources.filter(source => source.kind === 'bootloader');
50370
- if (bootloaderSources.length > 0) {
50371
- phases.push({
50372
- kind: 'bootloader-install',
50373
- installSources: bootloaderSources,
50374
- resourceSources: [],
50375
- }, {
50376
- kind: 'bootloader-verify',
50377
- installSources: [],
50378
- resourceSources: [],
50379
- });
50380
- }
50381
- const componentSources = installSources.filter(source => source.kind !== 'bootloader');
50382
- if (componentSources.length > 0) {
50383
- phases.push({
50384
- kind: 'component-install',
50385
- installSources: componentSources,
50386
- resourceSources: [],
50387
- });
50388
- }
50389
- phases.push({
50390
- kind: 'final-verify',
50391
- installSources: [],
50392
- resourceSources: [],
50393
- });
50394
- return phases;
50395
- }
50396
- executeProtocolV2Phases({ installSources, resourceSources, }) {
50397
- return __awaiter(this, void 0, void 0, function* () {
50398
- const phases = this.buildProtocolV2ExecutionPhases({
50399
- installSources,
50400
- resourceSources,
50401
- });
50402
- for (const phase of phases) {
50403
- if (phase.kind === 'final-verify') {
50404
- return this.completeProtocolV2FinalVerification();
50405
- }
50406
- if (phase.kind === 'resource-sync') {
50407
- yield this.enterProtocolV2BootloaderMode();
50408
- yield this.executeProtocolV2TransferPhase(phase);
50409
- }
50410
- else if (phase.kind === 'bootloader-install' || phase.kind === 'component-install') {
50411
- yield this.enterProtocolV2BootloaderMode();
50412
- yield this.executeProtocolV2TransferPhase(phase);
50413
- yield this.exitProtocolV2BootloaderToNormal();
50414
- }
50415
- else if (phase.kind === 'bootloader-verify') {
50416
- yield this.waitForProtocolV2FinalFeatures();
50417
- this.assertExpectedProtocolV2Versions(['boot']);
50418
- }
50419
- }
50420
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 execution has no final verification phase');
50421
- });
50422
- }
50423
- executeProtocolV2SourceUpdate({ installSources, resourceSources, }) {
50424
- return __awaiter(this, void 0, void 0, function* () {
50425
- return this.executeProtocolV2Phases({
50426
- installSources,
50427
- resourceSources,
50428
- });
50429
- });
50430
- }
50431
48797
  executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles, }) {
50432
48798
  return __awaiter(this, void 0, void 0, function* () {
50433
- const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
50434
- fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
48799
+ const orderedInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
50435
48800
  bootloaderBinary: bootloaderBinary !== null && bootloaderBinary !== void 0 ? bootloaderBinary : null,
48801
+ fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
50436
48802
  });
50437
- try {
50438
- const installSources = yield Promise.all(memoryInstallItems.map((item) => __awaiter(this, void 0, void 0, function* () {
50439
- return ({
50440
- fileName: item.fileName,
50441
- source: yield this.openProtocolV2MemorySource(item.binary),
50442
- targetId: item.targetId,
50443
- kind: item.kind,
50444
- });
50445
- })));
50446
- const resourceSources = yield Promise.all((resourceBundles !== null && resourceBundles !== void 0 ? resourceBundles : []).map((bundle) => __awaiter(this, void 0, void 0, function* () {
50447
- return ({
50448
- name: bundle.name,
50449
- source: yield this.openProtocolV2MemorySource(bundle.binary),
50450
- devicePath: bundle.devicePath,
50451
- version: bundle.version,
50452
- payloadHash: bundle.payloadHash,
50453
- headerHash: bundle.headerHash,
50454
- });
50455
- })));
50456
- return yield this.executeProtocolV2Phases({
50457
- installSources,
50458
- resourceSources,
50459
- });
50460
- }
50461
- finally {
50462
- yield this.closeProtocolV2PreparedSources();
50463
- }
50464
- });
50465
- }
50466
- executeProtocolV2TransferPhase({ installSources, resourceSources, }) {
50467
- return __awaiter(this, void 0, void 0, function* () {
50468
- let totalSize = installSources.reduce((total, item) => total + item.source.size, 0);
50469
- const resourcesToSync = [];
50470
- for (const resource of resourceSources) {
50471
- if (yield this.isProtocolV2ResourceBundleUpToDate(resource)) {
50472
- Log$5.log(`[FirmwareUpdateV4] skip RESC bundle ${resource.name}; already up to date`);
50473
- }
50474
- else {
50475
- resourcesToSync.push(resource);
50476
- totalSize += resource.source.size;
50477
- }
50478
- }
48803
+ let firmwareSize = 0;
48804
+ for (const item of orderedInstallItems)
48805
+ firmwareSize += item.binary.byteLength;
50479
48806
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
50480
48807
  let processedSize = 0;
50481
- for (const resource of resourcesToSync) {
50482
- processedSize = yield this.protocolV2SourceUpdateProcess({
50483
- source: resource.source,
50484
- filePath: resource.devicePath,
50485
- processedSize,
50486
- totalSize,
50487
- });
50488
- yield this.verifyProtocolV2StagedFile(resource.devicePath, resource.source.size);
48808
+ let totalSize = firmwareSize;
48809
+ if (resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) {
48810
+ const resourceTransfer = yield this.syncProtocolV2ResourceBundles(resourceBundles, firmwareSize);
48811
+ processedSize = resourceTransfer.processedSize;
48812
+ totalSize = resourceTransfer.totalSize;
50489
48813
  }
50490
- const stagedInstallTargets = [];
50491
- for (const item of installSources) {
50492
- const filePath = this.getProtocolV2InstallItemStagingPath(item);
50493
- processedSize = yield this.protocolV2SourceUpdateProcess({
50494
- source: item.source,
50495
- filePath,
50496
- processedSize,
50497
- totalSize,
50498
- });
50499
- yield this.verifyProtocolV2StagedFile(filePath, item.source.size);
50500
- stagedInstallTargets.push({
50501
- targetId: item.targetId,
50502
- path: filePath,
50503
- });
48814
+ if (orderedInstallItems.length === 0) {
48815
+ Log$5.log('[FirmwareUpdateV4] no firmware targets to install (RESC bundles only)');
48816
+ if (totalSize > 0) {
48817
+ this.postProgressMessage(100, 'transferData');
48818
+ }
48819
+ return;
50504
48820
  }
50505
- if (totalSize > 0) {
50506
- this.postProgressMessage(100, 'transferData');
48821
+ let transferredSize = processedSize;
48822
+ const transferStartTime = Date.now();
48823
+ const transferTransport = this.getProtocolV2FirmwareTransferTransport();
48824
+ const chunkSize = this.getProtocolV2FirmwareChunkSize();
48825
+ const onTransferredBytes = (bytes) => {
48826
+ transferredSize = bytes;
48827
+ };
48828
+ Log$5.log(`[FirmwareUpdateV4] transfer started transport=${transferTransport} total=${totalSize} bytes chunk=${chunkSize} bytes`);
48829
+ const stagedInstallTargets = [];
48830
+ try {
48831
+ for (const item of orderedInstallItems) {
48832
+ const filePath = this.getProtocolV2InstallItemStagingPath(item);
48833
+ Log$5.log(`[FirmwareUpdateV4] staging ${item.kind} via FilesystemFileWrite target=${item.targetId} path=${filePath} source=${item.fileName} bytes=${item.binary.byteLength}`);
48834
+ processedSize = yield this.protocolV2CommonUpdateProcess({
48835
+ payload: item.binary,
48836
+ filePath,
48837
+ processedSize,
48838
+ totalSize,
48839
+ onTransferredBytes,
48840
+ });
48841
+ transferredSize = processedSize;
48842
+ yield this.verifyProtocolV2StagedFile(filePath, item.binary.byteLength);
48843
+ stagedInstallTargets.push(Object.assign(Object.assign({}, item), { path: filePath }));
48844
+ }
48845
+ if (totalSize > 0) {
48846
+ this.postProgressMessage(100, 'transferData');
48847
+ }
48848
+ const elapsedMs = Date.now() - transferStartTime;
48849
+ Log$5.log(`[FirmwareUpdateV4] transfer finished transport=${transferTransport} bytes=${totalSize} elapsed=${(elapsedMs / 1000).toFixed(2)}s speed=${formatProtocolV2TransferSpeed(totalSize, elapsedMs)} KB/s`);
50507
48850
  }
50508
- if (stagedInstallTargets.length === 0) {
50509
- return;
48851
+ catch (error) {
48852
+ const elapsedMs = Date.now() - transferStartTime;
48853
+ Log$5.warn(`[FirmwareUpdateV4] transfer failed transport=${transferTransport} bytes=${transferredSize}/${totalSize} elapsed=${(elapsedMs / 1000).toFixed(2)}s speed=${formatProtocolV2TransferSpeed(transferredSize, elapsedMs)} KB/s`);
48854
+ throw error;
50510
48855
  }
50511
48856
  this.postTipMessage(exports.FirmwareUpdateTipMessage.ConfirmOnDevice);
50512
- const targets = stagedInstallTargets.map(item => ({
48857
+ const allTargets = stagedInstallTargets.map(item => ({
50513
48858
  target_id: item.targetId,
50514
48859
  path: item.path,
50515
48860
  }));
50516
- yield this.protocolV2StartFirmwareUpdate({ targets });
50517
- yield this.waitForProtocolV2FirmwareUpdateComplete(targets);
50518
- });
50519
- }
50520
- protocolV2SourceUpdateProcess({ source, filePath, processedSize, totalSize, }) {
50521
- return __awaiter(this, void 0, void 0, function* () {
50522
- let lastError;
50523
- for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
50524
- try {
50525
- yield writeFirmwareByteSource({
50526
- source,
50527
- chunkSize: this.getProtocolV2FirmwareChunkSize(),
50528
- write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
50529
- const chunkEnd = sourceOffset + length;
50530
- const progress = getProtocolV2DeviceTransferProgress(processedSize + sourceOffset, processedSize + chunkEnd, totalSize);
50531
- const response = yield this.fileWriteChunk(filePath, source.size, sourceOffset, data, first, progress);
50532
- const rawProcessedByte = response.message.processed_byte;
50533
- const nextOffset = rawProcessedByte === undefined ? chunkEnd : Number(rawProcessedByte);
50534
- if (!Number.isFinite(nextOffset) || nextOffset !== chunkEnd) {
50535
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `invalid processed_byte ${rawProcessedByte} for offset ${sourceOffset}`);
50536
- }
50537
- this.postProgressMessage(progress, 'transferData');
50538
- return length;
50539
- }),
50540
- });
50541
- return processedSize + source.size;
50542
- }
50543
- catch (error) {
50544
- lastError = error;
50545
- if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
50546
- yield this.recoverProtocolV2FileTransfer();
50547
- }
50548
- }
50549
- }
50550
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`);
48861
+ Log$5.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest targets=${JSON.stringify(allTargets)}`);
48862
+ yield this.protocolV2StartFirmwareUpdate({ targets: allTargets });
48863
+ yield this.waitForProtocolV2FirmwareUpdateComplete(allTargets);
50551
48864
  });
50552
48865
  }
50553
48866
  getProtocolV2InstallItemStagingPath(item) {
@@ -50564,7 +48877,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50564
48877
  }
50565
48878
  });
50566
48879
  }
50567
- assertProtocolV2TargetStatus(statusTargets, expectedTargetIds, expectedPaths = new Map()) {
48880
+ assertProtocolV2TargetStatus(statusTargets, expectedTargetIds) {
50568
48881
  var _a, _b, _c;
50569
48882
  Log$5.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateStatus records=${JSON.stringify(statusTargets)}`);
50570
48883
  const failedTarget = statusTargets.find(target => {
@@ -50583,34 +48896,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50583
48896
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareError, `Protocol V2 firmware target failed: target=${failedTarget.target_id} status=${(_a = failedTarget.status) !== null && _a !== void 0 ? _a : 'unknown'} payloadVersion=${(_b = failedTarget.payload_version) !== null && _b !== void 0 ? _b : 'unknown'} path=${(_c = failedTarget.path) !== null && _c !== void 0 ? _c : 'unknown'}`);
50584
48897
  }
50585
48898
  const matchingTargets = statusTargets.filter(target => { var _a; return expectedTargetIds.has((_a = normalizeProtocolV2TargetId(target.target_id)) !== null && _a !== void 0 ? _a : -1); });
50586
- const seenTargetIds = new Set();
50587
- for (const target of matchingTargets) {
50588
- const targetId = normalizeProtocolV2TargetId(target.target_id);
50589
- if (targetId === undefined ||
50590
- seenTargetIds.has(targetId) ||
50591
- (target.path && expectedPaths.get(targetId) && target.path !== expectedPaths.get(targetId))) {
50592
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 install status conflicts with target ${target.target_id}`);
50593
- }
50594
- seenTargetIds.add(targetId);
50595
- }
50596
48899
  const completedTargets = matchingTargets.filter(target => isProtocolV2TargetStatusFinished(target.status));
50597
48900
  if (completedTargets.length === expectedTargetIds.size && expectedTargetIds.size > 0) {
50598
- for (const target of completedTargets) {
50599
- const targetId = normalizeProtocolV2TargetId(target.target_id);
50600
- const payloadVersion = toProtocolV2FiniteNumber(target.payload_version);
50601
- if (targetId === undefined) {
50602
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 completed target identity is invalid');
50603
- }
50604
- const expectedVersion = this.getExpectedProtocolV2TargetVersion(targetId);
50605
- if (expectedVersion !== undefined && payloadVersion !== undefined) {
50606
- if (payloadVersion !== expectedVersion) {
50607
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareVerificationFailed, `Protocol V2 target ${targetId} reached payload version ${payloadVersion}, expected ${expectedVersion}`);
50608
- }
50609
- }
50610
- if (payloadVersion !== undefined) {
50611
- this.protocolV2CompletedTargetVersions.set(targetId, payloadVersion);
50612
- }
50613
- }
50614
48901
  this.postProgressMessage(100, 'installingFirmware');
50615
48902
  return true;
50616
48903
  }
@@ -50623,10 +48910,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50623
48910
  return false;
50624
48911
  }
50625
48912
  waitForProtocolV2FirmwareUpdateComplete(targets) {
50626
- var _a, _b;
48913
+ var _a;
50627
48914
  return __awaiter(this, void 0, void 0, function* () {
50628
48915
  const expectedTargetIds = new Set(targets.map(target => target.target_id));
50629
- const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
50630
48916
  const startTime = Date.now();
50631
48917
  let lastError;
50632
48918
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
@@ -50641,7 +48927,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50641
48927
  path: true,
50642
48928
  },
50643
48929
  }, { timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT });
50644
- if (this.assertProtocolV2TargetStatus(((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : []), expectedTargetIds, expectedPaths)) {
48930
+ if (this.assertProtocolV2TargetStatus(((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : []), expectedTargetIds)) {
50645
48931
  return;
50646
48932
  }
50647
48933
  lastError = new Error('Protocol V2 firmware targets are still installing');
@@ -50652,24 +48938,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50652
48938
  throw error;
50653
48939
  }
50654
48940
  if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
50655
- try {
50656
- const deviceInfo = yield requestProtocolV2DeviceInfo({
50657
- commands: this.device.getCommands(),
50658
- timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
50659
- });
50660
- this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
50661
- const observed = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
50662
- if (observed.mode === 'normal' && !observed.bootloaderMode) {
50663
- return;
50664
- }
50665
- lastError = new Error('Protocol V2 status endpoint is unavailable outside normal mode');
50666
- }
50667
- catch (probeError) {
50668
- lastError = probeError;
50669
- }
50670
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware install status is unavailable: ${this.normalizeErrorMessage(lastError)}`, {
50671
- firmwareUpdateCode: 'FirmwareInstallStatusUnavailable',
50672
- });
48941
+ Log$5.log('[FirmwareUpdateV4] firmware status endpoint unavailable after reboot; continue with normal-mode verification');
48942
+ return;
50673
48943
  }
50674
48944
  lastError = error;
50675
48945
  Log$5.log('[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ', error);
@@ -50683,10 +48953,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50683
48953
  if (error instanceof hdShared.HardwareError && error.errorCode === hdShared.HardwareErrorCode.FirmwareError) {
50684
48954
  throw error;
50685
48955
  }
50686
- if (error instanceof hdShared.HardwareError &&
50687
- ((_b = error.params) === null || _b === void 0 ? void 0 : _b.firmwareUpdateCode) === 'FirmwareInstallStatusUnavailable') {
50688
- throw error;
50689
- }
50690
48956
  Log$5.log('Protocol V2 firmware install device readiness probe failed: ', error);
50691
48957
  }
50692
48958
  yield hdShared.wait(1000);
@@ -50699,7 +48965,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50699
48965
  yield this.reconnectProtocolV2Device();
50700
48966
  yield this.verifyProtocolV2ReconnectIdentity();
50701
48967
  yield this.protocolV2Reboot(hdTransport.DeviceRebootType.Normal);
50702
- this.protocolV2ExecutionInLoader = false;
50703
48968
  });
50704
48969
  }
50705
48970
  waitForProtocolV2FinalFeatures() {
@@ -50708,7 +48973,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50708
48973
  const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
50709
48974
  const bleVersion = getDeviceBLEFirmwareVersion(features).join('.');
50710
48975
  const firmwareVersion = getDeviceFirmwareVersion(features).join('.');
50711
- this.protocolV2LatestFinalFeatures = features;
50712
48976
  if (firmwareVersion === '0.0.0') {
50713
48977
  Log$5.warn('Protocol V2 firmware update finished but app firmware version is still 0.0.0. This is allowed for Pro2 debug BLE-only update flows.');
50714
48978
  }
@@ -50719,18 +48983,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50719
48983
  };
50720
48984
  });
50721
48985
  }
50722
- completeProtocolV2FinalVerification() {
50723
- return __awaiter(this, void 0, void 0, function* () {
50724
- if (this.protocolV2ExecutionInLoader || this.isProtocolV2BootloaderMode()) {
50725
- yield this.exitProtocolV2BootloaderToNormal();
50726
- }
50727
- const versions = yield this.waitForProtocolV2FinalFeatures();
50728
- this.assertExpectedProtocolV2Versions();
50729
- this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdateCompleted);
50730
- DevicePool.resetState();
50731
- return versions;
50732
- });
50733
- }
50734
48986
  waitForProtocolV2ReconnectAndFeatures(timeout) {
50735
48987
  return __awaiter(this, void 0, void 0, function* () {
50736
48988
  const startTime = Date.now();
@@ -50806,6 +49058,66 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50806
49058
  isProtocolV2ReconnectIdentityError(error) {
50807
49059
  return this.normalizeErrorMessage(error).includes('Protocol V2 reconnect physical identity');
50808
49060
  }
49061
+ protocolV2CommonUpdateProcess(params) {
49062
+ return __awaiter(this, void 0, void 0, function* () {
49063
+ let lastError;
49064
+ for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
49065
+ try {
49066
+ return yield this.protocolV2WriteWholeFile(params);
49067
+ }
49068
+ catch (error) {
49069
+ lastError = error;
49070
+ Log$5.error(`Protocol V2 file transfer failed path=${params.filePath} attempt=${attempt}/${PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT}; restarting from offset 0`, error);
49071
+ if (attempt === PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
49072
+ break;
49073
+ }
49074
+ yield this.recoverProtocolV2FileTransfer();
49075
+ }
49076
+ }
49077
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`);
49078
+ });
49079
+ }
49080
+ protocolV2WriteWholeFile({ payload, filePath, processedSize, totalSize, onTransferredBytes, }) {
49081
+ return __awaiter(this, void 0, void 0, function* () {
49082
+ const chunkSize = this.getProtocolV2FirmwareChunkSize();
49083
+ let offset = 0;
49084
+ const getUploadProgress = (fileOffset) => {
49085
+ if (totalSize !== undefined && processedSize !== undefined) {
49086
+ return Math.min(Math.ceil(((processedSize + fileOffset) / totalSize) * 100), 99);
49087
+ }
49088
+ return Math.min(Math.ceil((fileOffset / payload.byteLength) * 100), 99);
49089
+ };
49090
+ while (offset < payload.byteLength) {
49091
+ const chunkEnd = Math.min(offset + chunkSize, payload.byteLength);
49092
+ const chunkLength = chunkEnd - offset;
49093
+ const chunk = payload.slice(offset, chunkEnd);
49094
+ const overwrite = offset === 0;
49095
+ const progress = getProtocolV2DeviceTransferProgress((processedSize !== null && processedSize !== void 0 ? processedSize : 0) + offset, (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + chunkEnd, totalSize !== null && totalSize !== void 0 ? totalSize : payload.byteLength);
49096
+ const writeRes = yield this.fileWriteChunk(filePath, payload.byteLength, offset, chunk, overwrite, progress);
49097
+ const rawProcessedByte = writeRes.message.processed_byte;
49098
+ const processedByte = Number(rawProcessedByte);
49099
+ const nextOffset = rawProcessedByte === undefined ? offset + chunkLength : processedByte;
49100
+ if (!Number.isFinite(nextOffset) || nextOffset <= offset || nextOffset > chunkEnd) {
49101
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `invalid processed_byte ${writeRes.message.processed_byte} for offset ${offset}`);
49102
+ }
49103
+ offset = nextOffset;
49104
+ onTransferredBytes === null || onTransferredBytes === void 0 ? void 0 : onTransferredBytes((processedSize !== null && processedSize !== void 0 ? processedSize : 0) + offset);
49105
+ this.postProgressMessage(getUploadProgress(offset), 'transferData');
49106
+ }
49107
+ return totalSize !== undefined ? (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + payload.byteLength : 0;
49108
+ });
49109
+ }
49110
+ getProtocolV2FirmwareTransferTransport() {
49111
+ const env = DataManager.getSettings('env');
49112
+ if (env && DataManager.isBleConnect(env)) {
49113
+ return 'BLE';
49114
+ }
49115
+ if (env &&
49116
+ (DataManager.isBrowserWebUsb(env) || DataManager.isDesktopWebUsb(env) || env === 'web')) {
49117
+ return 'WebUSB';
49118
+ }
49119
+ return env !== null && env !== void 0 ? env : 'unknown';
49120
+ }
50809
49121
  fileWriteChunk(filePath, totalFileSize, offset, chunk, overwrite, progress) {
50810
49122
  var _a;
50811
49123
  return __awaiter(this, void 0, void 0, function* () {
@@ -60685,6 +58997,7 @@ class NeoSignTransaction extends BaseMethod {
60685
58997
  var ApiMethods = /*#__PURE__*/Object.freeze({
60686
58998
  __proto__: null,
60687
58999
  testInitializeDeviceDuration: TestInitializeDeviceDuration,
59000
+ testProtocolV2Ping: Ping,
60688
59001
  preInitialize: PreInitialize,
60689
59002
  searchDevices: SearchDevices,
60690
59003
  getFeatures: GetFeatures,
@@ -61230,7 +59543,7 @@ class ProtocolV2UiInteractionCoordinator {
61230
59543
 
61231
59544
  const Log$1 = getLogger(exports.LoggerNames.Core);
61232
59545
  function runMethodWithUnlockRetry(method, device, uiCoordinator) {
61233
- var _a;
59546
+ var _a, _b, _c, _d;
61234
59547
  return __awaiter(this, void 0, void 0, function* () {
61235
59548
  const shouldEmitUi = isProtocolV2UiEnabled(method);
61236
59549
  const shouldUnlockBeforeRun = device.isProtocolV2() && method.unlockPolicy !== 'none' && ((_a = device.features) === null || _a === void 0 ? void 0 : _a.unlocked) === false;
@@ -61263,6 +59576,15 @@ function runMethodWithUnlockRetry(method, device, uiCoordinator) {
61263
59576
  }
61264
59577
  yield device.unlockDevice();
61265
59578
  Log$1.debug('Protocol V2 unlock completed', { method: method.name });
59579
+ const expectedPassphraseState = ((_b = method.payload) === null || _b === void 0 ? void 0 : _b.useEmptyPassphrase)
59580
+ ? undefined
59581
+ : (_d = (_c = method.payload) === null || _c === void 0 ? void 0 : _c.passphraseState) !== null && _d !== void 0 ? _d : device.passphraseState;
59582
+ if (method.useDevicePassphraseState &&
59583
+ typeof expectedPassphraseState === 'string' &&
59584
+ expectedPassphraseState.length > 0) {
59585
+ yield restoreProtocolV2WalletSession(device, expectedPassphraseState);
59586
+ Log$1.debug('Protocol V2 wallet session restored after unlock', { method: method.name });
59587
+ }
61266
59588
  if (shouldEmitUi) {
61267
59589
  uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.resumeMethodInteraction();
61268
59590
  }
@@ -61360,7 +59682,6 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
61360
59682
  }
61361
59683
  return createResponseMessage((_b = method === null || method === void 0 ? void 0 : method.responseID) !== null && _b !== void 0 ? _b : message.id, false, { error });
61362
59684
  }
61363
- DevicePool.emitter.on(DEVICE.CONNECT, onDeviceConnectHandler);
61364
59685
  if (!method.useDevice) {
61365
59686
  updateMethodRequestContext(method, { status: 'running' });
61366
59687
  try {
@@ -61394,7 +59715,6 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
61394
59715
  });
61395
59716
  const handlePreWarmSignal = (context, message, method) => __awaiter(void 0, void 0, void 0, function* () {
61396
59717
  const createAckResponse = () => {
61397
- DevicePool.emitter.removeListener(DEVICE.CONNECT, onDeviceConnectHandler);
61398
59718
  completeMethodRequestContext(method);
61399
59719
  method.dispose();
61400
59720
  return createResponseMessage(method.responseID, true, true);
@@ -61821,8 +60141,14 @@ function connectDeviceForBle(method, device, retryCount = 0) {
61821
60141
  var _a;
61822
60142
  return __awaiter(this, void 0, void 0, function* () {
61823
60143
  try {
61824
- yield device.acquire(method.payload.connectProtocol);
60144
+ const shouldAcquire = !device.hasDeviceAcquire() || !device.commands || device.commands.disposed;
60145
+ if (shouldAcquire) {
60146
+ yield device.acquire(method.payload.connectProtocol);
60147
+ }
61825
60148
  if ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.onlyConnectBleDevice) {
60149
+ if (shouldAcquire) {
60150
+ DevicePool.emitter.emit(DEVICE.CONNECT, device);
60151
+ }
61826
60152
  return;
61827
60153
  }
61828
60154
  if (!canSkipInitialize(method, device)) {
@@ -61832,6 +60158,9 @@ function connectDeviceForBle(method, device, retryCount = 0) {
61832
60158
  passphraseState: initOptions.passphraseState,
61833
60159
  });
61834
60160
  }
60161
+ if (shouldAcquire) {
60162
+ DevicePool.emitter.emit(DEVICE.CONNECT, device);
60163
+ }
61835
60164
  }
61836
60165
  catch (err) {
61837
60166
  if ((err.errorCode === hdShared.HardwareErrorCode.BleTimeoutError ||
@@ -62069,7 +60398,6 @@ const cleanup = () => {
62069
60398
  };
62070
60399
  const removeDeviceListener = (device) => {
62071
60400
  device.removeAllListeners();
62072
- DevicePool.emitter.removeAllListeners(DEVICE.CONNECT);
62073
60401
  };
62074
60402
  const closePopup = () => {
62075
60403
  postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_WINDOW));
@@ -62087,6 +60415,16 @@ const onDeviceDisconnectHandler = (device) => {
62087
60415
  return;
62088
60416
  postMessage(createDeviceMessage(DEVICE.DISCONNECT, { device: deviceObject }));
62089
60417
  };
60418
+ const onTransportDeviceDisconnectHandler = (event) => {
60419
+ var _a, _b;
60420
+ const device = (_b = (_a = deviceCacheMap.get(event.connectId)) !== null && _a !== void 0 ? _a : DevicePool.devicesCache[event.connectId]) !== null && _b !== void 0 ? _b : DevicePool.getDeviceByPath(event.connectId);
60421
+ if (!device) {
60422
+ Log.debug('Ignoring transport disconnect for an unknown device:', event.connectId);
60423
+ return;
60424
+ }
60425
+ device.markTransportDisconnected();
60426
+ DevicePool.emitter.emit(DEVICE.DISCONNECT, device);
60427
+ };
62090
60428
  const onDevicePinHandler = (...[device, type, callback]) => __awaiter(void 0, void 0, void 0, function* () {
62091
60429
  Log.log('request Input PIN');
62092
60430
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PIN, device);
@@ -62314,7 +60652,12 @@ const initCore = () => {
62314
60652
  };
62315
60653
  const initConnector = () => {
62316
60654
  _connector = new DeviceConnector();
60655
+ DevicePool.emitter.removeListener(DEVICE.CONNECT, onDeviceConnectHandler);
60656
+ DevicePool.emitter.removeListener(DEVICE.DISCONNECT, onDeviceDisconnectHandler);
60657
+ DevicePool.emitter.removeListener(hdTransport.TRANSPORT_EVENT.DEVICE_DISCONNECT, onTransportDeviceDisconnectHandler);
60658
+ DevicePool.emitter.on(DEVICE.CONNECT, onDeviceConnectHandler);
62317
60659
  DevicePool.emitter.on(DEVICE.DISCONNECT, onDeviceDisconnectHandler);
60660
+ DevicePool.emitter.on(hdTransport.TRANSPORT_EVENT.DEVICE_DISCONNECT, onTransportDeviceDisconnectHandler);
62318
60661
  return _connector;
62319
60662
  };
62320
60663
  const initTransport = (Transport, plugin) => {
@@ -62456,7 +60799,6 @@ exports.getEnv = getEnv;
62456
60799
  exports.getFirmwareType = getFirmwareType;
62457
60800
  exports.getFirmwareUpdateField = getFirmwareUpdateField;
62458
60801
  exports.getFirmwareUpdateFieldArray = getFirmwareUpdateFieldArray;
62459
- exports.getFirmwareUpdateHostBindingGeneration = getFirmwareUpdateHostBindingGeneration;
62460
60802
  exports.getHDPath = getHDPath;
62461
60803
  exports.getHomeScreenDefaultList = getHomeScreenDefaultList;
62462
60804
  exports.getHomeScreenHex = getHomeScreenHex;
@@ -62482,12 +60824,10 @@ exports.parseConnectSettings = parseConnectSettings;
62482
60824
  exports.parseMessage = parseMessage;
62483
60825
  exports.patchFeatures = patchFeatures;
62484
60826
  exports.preloadSessionCache = preloadSessionCache;
62485
- exports.registerFirmwareUpdateHostBinding = registerFirmwareUpdateHostBinding;
62486
60827
  exports.safeThrowError = safeThrowError;
62487
60828
  exports.setLoggerPostMessage = setLoggerPostMessage;
62488
60829
  exports.supportInputPinOnSoftware = supportInputPinOnSoftware;
62489
60830
  exports.switchTransport = switchTransport;
62490
- exports.unregisterFirmwareUpdateHostBinding = unregisterFirmwareUpdateHostBinding;
62491
60831
  exports.updateRequestContext = updateRequestContext;
62492
60832
  exports.versionCompare = versionCompare;
62493
60833
  exports.versionSplit = versionSplit;