@onekeyfe/hd-core 1.2.0-alpha.22 → 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 (151) hide show
  1. package/__tests__/DeviceCommands.test.ts +43 -8
  2. package/__tests__/connectSettings.test.ts +5 -47
  3. package/__tests__/device-lifecycle-events.test.ts +59 -0
  4. package/__tests__/device-settings.test.ts +1 -1
  5. package/__tests__/device-wallet-session-store.test.ts +41 -0
  6. package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +30 -39
  7. package/__tests__/logBlockEvent.test.ts +17 -0
  8. package/__tests__/open-wallet-session.test.ts +233 -111
  9. package/__tests__/protocol-v2-ping.test.ts +28 -0
  10. package/__tests__/protocol-v2.test.ts +513 -313
  11. package/__tests__/public-pro2-api-boundary.test.ts +22 -0
  12. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  13. package/dist/api/FirmwareUpdateV2.d.ts +0 -11
  14. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  15. package/dist/api/FirmwareUpdateV3.d.ts +3 -7
  16. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  17. package/dist/api/FirmwareUpdateV4.d.ts +5 -21
  18. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  19. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  20. package/dist/api/OpenWalletSession.d.ts +1 -8
  21. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  22. package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
  23. package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
  24. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  25. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -7
  26. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  27. package/dist/api/firmware/getBinary.d.ts +0 -7
  28. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  29. package/dist/api/firmware/updateBootloader.d.ts +0 -2
  30. package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
  31. package/dist/api/firmware/uploadFirmware.d.ts +1 -9
  32. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
  33. package/dist/api/index.d.ts +1 -0
  34. package/dist/api/index.d.ts.map +1 -1
  35. package/dist/api/protocol-v2/Ping.d.ts +2 -0
  36. package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
  37. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  38. package/dist/core/index.d.ts.map +1 -1
  39. package/dist/data-manager/DataManager.d.ts +0 -1
  40. package/dist/data-manager/DataManager.d.ts.map +1 -1
  41. package/dist/data-manager/connectSettings.d.ts.map +1 -1
  42. package/dist/device/Device.d.ts +3 -2
  43. package/dist/device/Device.d.ts.map +1 -1
  44. package/dist/device/DeviceCommands.d.ts.map +1 -1
  45. package/dist/events/device.d.ts +1 -0
  46. package/dist/events/device.d.ts.map +1 -1
  47. package/dist/events/logBlockEvent.d.ts.map +1 -1
  48. package/dist/events/ui-request.d.ts +1 -0
  49. package/dist/events/ui-request.d.ts.map +1 -1
  50. package/dist/index.d.ts +98 -278
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +876 -2647
  53. package/dist/inject.d.ts.map +1 -1
  54. package/dist/lowLevelInject.d.ts.map +1 -1
  55. package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -1
  56. package/dist/protocols/protocol-v2/unlockRetry.d.ts +2 -3
  57. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
  58. package/dist/protocols/protocol-v2/walletSession.d.ts +12 -0
  59. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  60. package/dist/topLevelInject.d.ts.map +1 -1
  61. package/dist/types/api/checkAllFirmwareRelease.d.ts +0 -3
  62. package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
  63. package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
  64. package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
  65. package/dist/types/api/export.d.ts +1 -4
  66. package/dist/types/api/export.d.ts.map +1 -1
  67. package/dist/types/api/firmwareUpdate.d.ts +0 -69
  68. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  69. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  70. package/dist/types/api/index.d.ts +4 -10
  71. package/dist/types/api/index.d.ts.map +1 -1
  72. package/dist/types/api/openWalletSession.d.ts +0 -12
  73. package/dist/types/api/openWalletSession.d.ts.map +1 -1
  74. package/dist/types/api/protocolV2.d.ts +4 -0
  75. package/dist/types/api/protocolV2.d.ts.map +1 -1
  76. package/dist/types/settings.d.ts +0 -13
  77. package/dist/types/settings.d.ts.map +1 -1
  78. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  79. package/dist/utils/patch.d.ts +1 -1
  80. package/dist/utils/patch.d.ts.map +1 -1
  81. package/package.json +4 -4
  82. package/src/api/CheckAllFirmwareRelease.ts +3 -16
  83. package/src/api/FirmwareUpdateV2.ts +119 -284
  84. package/src/api/FirmwareUpdateV3.ts +55 -248
  85. package/src/api/FirmwareUpdateV4.ts +293 -751
  86. package/src/api/GetPassphraseState.ts +11 -5
  87. package/src/api/OpenWalletSession.ts +23 -86
  88. package/src/api/device/DeviceUpdateBootloader.ts +6 -114
  89. package/src/api/device/DeviceWipe.ts +2 -0
  90. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +0 -50
  91. package/src/api/firmware/updateBootloader.ts +4 -19
  92. package/src/api/firmware/uploadFirmware.ts +22 -140
  93. package/src/api/index.ts +1 -0
  94. package/src/api/protocol-v2/Ping.ts +32 -1
  95. package/src/core/index.ts +40 -7
  96. package/src/data/messages/messages-protocol-v2.json +49 -56
  97. package/src/data-manager/DataManager.ts +33 -33
  98. package/src/data-manager/connectSettings.ts +0 -11
  99. package/src/device/Device.ts +29 -8
  100. package/src/device/DeviceCommands.ts +43 -151
  101. package/src/events/device.ts +1 -0
  102. package/src/events/logBlockEvent.ts +1 -15
  103. package/src/events/ui-request.ts +1 -0
  104. package/src/index.ts +0 -5
  105. package/src/inject.ts +4 -22
  106. package/src/lowLevelInject.ts +1 -5
  107. package/src/protocols/protocol-v2/deviceSession.ts +1 -1
  108. package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +0 -1
  109. package/src/protocols/protocol-v2/unlockRetry.ts +20 -3
  110. package/src/protocols/protocol-v2/walletSession.ts +57 -18
  111. package/src/topLevelInject.ts +1 -5
  112. package/src/types/api/checkAllFirmwareRelease.ts +0 -3
  113. package/src/types/api/deviceUpdateBootloader.ts +0 -6
  114. package/src/types/api/export.ts +0 -18
  115. package/src/types/api/firmwareUpdate.ts +0 -76
  116. package/src/types/api/getPassphraseState.ts +4 -3
  117. package/src/types/api/index.ts +3 -14
  118. package/src/types/api/openWalletSession.ts +0 -19
  119. package/src/types/api/protocolV2.ts +10 -0
  120. package/src/types/settings.ts +0 -13
  121. package/src/utils/deviceInfoUtils.ts +2 -3
  122. package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
  123. package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
  124. package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
  125. package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -326
  126. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -200
  127. package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
  128. package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -26
  129. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
  130. package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
  131. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
  132. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
  133. package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
  134. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -24
  135. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
  136. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -25
  137. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
  138. package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
  139. package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
  140. package/dist/types/api/firmwareUpdatePlan.d.ts +0 -27
  141. package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
  142. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
  143. package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
  144. package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
  145. package/src/api/firmware/FirmwareHostBinding.ts +0 -100
  146. package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
  147. package/src/api/firmware/FirmwareUpdatePlan.ts +0 -621
  148. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -378
  149. package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
  150. package/src/types/api/firmwareUpdatePlan.ts +0 -36
  151. 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
- var lodash = require('lodash');
10
6
  var hdTransport = require('@onekeyfe/hd-transport');
7
+ var hdShared = require('@onekeyfe/hd-shared');
11
8
  var axios = require('axios');
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,1120 +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
- const deviceType = getDeviceType(features);
441
- if (deviceType == null)
442
- return null;
443
- if ('label' in features && typeof features.label === 'string' && !lodash.isEmpty(features.label)) {
444
- return features.label;
445
- }
446
- const bleName = getDeviceBleName(features);
447
- if (!lodash.isEmpty(bleName))
448
- return bleName;
449
- if (deviceType === hdShared.EDeviceType.ClassicPure) {
450
- return 'OneKey Classic 1S';
451
- }
452
- return `OneKey ${deviceType.charAt(0).toUpperCase() + deviceType.slice(1)}`;
453
- };
454
- const getMethodVersionRange = (features, getVersionRange) => {
455
- const deviceType = getDeviceType(features);
456
- const versionRange = getVersionRange(deviceType);
457
- if (versionRange) {
458
- return versionRange;
459
- }
460
- const modelFallbacks = [
461
- 'model_classic1s',
462
- 'model_classic',
463
- 'model_mini',
464
- 'model_touch',
465
- ];
466
- for (const model of modelFallbacks) {
467
- if (DeviceModelToTypes[model].includes(deviceType)) {
468
- const versionRange = getVersionRange(model);
469
- if (versionRange) {
470
- return versionRange;
471
- }
472
- }
473
- }
474
- return undefined;
475
- };
476
- const isMethodVersionRangeUnsupported = (versionRange) => (versionRange === null || versionRange === void 0 ? void 0 : versionRange.unsupported) === true;
477
- const getFirmwareType = (features) => resolveDeviceFirmwareType(features);
478
-
479
- const EMPTY_VERSION = [0, 0, 0];
480
- const parseDeviceVersion = (version) => {
481
- const parsed = version ? semver__default["default"].parse(version) : null;
482
- return parsed ? [parsed.major, parsed.minor, parsed.patch] : [...EMPTY_VERSION];
483
- };
484
- const getDeviceFirmwareVersion = (features) => parseDeviceVersion(resolveDeviceFirmwareVersion(features));
485
- const getDeviceBootloaderVersion = (features) => parseDeviceVersion(resolveDeviceBootloaderVersion(features));
486
- const getDeviceBoardloaderVersion = (features) => parseDeviceVersion(resolveDeviceBoardVersion(features));
487
- const getDeviceBLEFirmwareVersion = (features) => parseDeviceVersion(resolveDeviceBleFirmwareVersion(features));
488
-
489
- const PROTOCOL_V2_TARGETS = {
490
- BOOTLOADER: 'boot',
491
- APPLICATION_P1: 'app_v1',
492
- APPLICATION_P2: 'app_v2',
493
- COPROCESSOR: 'coprocessor',
494
- SE01: 'se01',
495
- SE02: 'se02',
496
- SE03: 'se03',
497
- SE04: 'se04',
498
- };
499
- const asRecord = (value) => value && typeof value === 'object' && !Array.isArray(value)
500
- ? value
501
- : undefined;
502
- const asRelease = (release) => asRecord(release === null || release === void 0 ? void 0 : release.release);
503
- const asString = (value) => typeof value === 'string' && value.length > 0 ? value : undefined;
504
- const asVersion = (value) => {
505
- if (!Array.isArray(value) ||
506
- value.length !== 3 ||
507
- value.some(part => typeof part !== 'number' || !Number.isSafeInteger(part) || part < 0)) {
508
- return undefined;
509
- }
510
- return value.join('.');
511
- };
512
- const asIntegrity = ({ size, sha256: value, }) => {
513
- const sha256Value = typeof value === 'string' && /^[a-f0-9]{64}$/iu.test(value) ? value.toLowerCase() : undefined;
514
- return Object.assign(Object.assign({}, (Number.isSafeInteger(size) && size > 0 ? { expectedSize: size } : {})), (sha256Value ? { expectedSha256: sha256Value } : {}));
515
- };
516
- const isUpgrade = (release) => (release === null || release === void 0 ? void 0 : release.status) === 'required' ||
517
- (release === null || release === void 0 ? void 0 : release.status) === 'outdated' ||
518
- (release === null || release === void 0 ? void 0 : release.shouldUpdate) === true;
519
- const assertArtifactUrl = (value, label) => {
520
- const raw = asString(value);
521
- if (!raw) {
522
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${label} has no downloadable artifact`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
523
- }
524
- const parsed = new URL(raw);
525
- if (parsed.protocol !== 'https:' ||
526
- parsed.port !== '' ||
527
- parsed.username ||
528
- parsed.password ||
529
- parsed.hash) {
530
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${label} URL is not canonical HTTPS`, {
531
- firmwareUpdateCode: 'FirmwarePlanInvalid',
532
- });
533
- }
534
- return raw;
535
- };
536
- const canonicalizeFirmwareUpdateContract = (value) => {
537
- if (Array.isArray(value)) {
538
- return value.map(canonicalizeFirmwareUpdateContract);
539
- }
540
- if (value && typeof value === 'object') {
541
- return Object.keys(value)
542
- .sort()
543
- .reduce((result, key) => {
544
- const item = value[key];
545
- if (item !== undefined) {
546
- result[key] = canonicalizeFirmwareUpdateContract(item);
547
- }
548
- return result;
549
- }, {});
550
- }
551
- return value;
552
- };
553
- const digestFirmwareUpdateContract = (value) => utils.bytesToHex(sha256.sha256(new TextEncoder().encode(JSON.stringify(canonicalizeFirmwareUpdateContract(value)))));
554
- const digestFirmwareUpdatePlan = (plan) => digestFirmwareUpdateContract(plan);
555
- const planError = (message) => {
556
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
557
- firmwareUpdateCode: 'FirmwarePlanInvalid',
558
- });
559
- };
560
- const assertExactKeys = (value, required, optional = []) => {
561
- const allowed = new Set([...required, ...optional]);
562
- if (required.some(key => !Object.prototype.hasOwnProperty.call(value, key)) ||
563
- Object.keys(value).some(key => !allowed.has(key))) {
564
- planError('Firmware update plan contains an invalid field set');
565
- }
566
- };
567
- const assertBoundedString = (value, label, maxLength = 256) => {
568
- if (typeof value !== 'string' || value.length === 0 || value.length > maxLength) {
569
- return planError(`Firmware update plan ${label} is invalid`);
570
- }
571
- return value;
572
- };
573
- const FIRMWARE_UPDATE_PLAN_TARGETS = new Set([
574
- 'firmware',
575
- 'ble',
576
- 'bootloader',
577
- 'resource',
578
- 'boot',
579
- 'app_v1',
580
- 'app_v2',
581
- 'coprocessor',
582
- 'se01',
583
- 'se02',
584
- 'se03',
585
- 'se04',
586
- ]);
587
- const FIRMWARE_UPDATE_PLAN_ROLES = new Set([
588
- 'firmware',
589
- 'ble',
590
- 'bootloader',
591
- 'resource',
592
- 'component',
593
- 'resourceBundle',
594
- ]);
595
- const PLAN_CONTAINERS = new Set(['raw', 'zip']);
596
- const PLAN_PLATFORMS = new Set([
597
- 'native',
598
- 'desktop',
599
- 'ext',
600
- 'web',
601
- 'web-embed',
602
- ]);
603
- const assertFirmwareUpdatePlan = (value) => {
604
- const plan = asRecord(value);
605
- if (!plan) {
606
- return planError('Firmware update plan must be an object');
607
- }
608
- assertExactKeys(plan, [
609
- 'schemaVersion',
610
- 'planDigest',
611
- 'executor',
612
- 'deviceIdentity',
613
- 'deviceModel',
614
- 'firmwareType',
615
- 'platform',
616
- 'artifacts',
617
- 'targetsToUpdate',
618
- ]);
619
- if (plan.schemaVersion !== 2 ||
620
- typeof plan.planDigest !== 'string' ||
621
- !/^[a-f0-9]{64}$/u.test(plan.planDigest) ||
622
- (plan.executor !== 'v2' && plan.executor !== 'v3' && plan.executor !== 'v4') ||
623
- !PLAN_PLATFORMS.has(plan.platform) ||
624
- (plan.firmwareType !== hdShared.EFirmwareType.Universal &&
625
- plan.firmwareType !== hdShared.EFirmwareType.BitcoinOnly)) {
626
- return planError('Firmware update plan header is invalid');
627
- }
628
- assertBoundedString(plan.deviceIdentity, 'device identity');
629
- assertBoundedString(plan.deviceModel, 'device model', 64);
630
- if (!Array.isArray(plan.artifacts) || plan.artifacts.length > 128) {
631
- return planError('Firmware update plan artifact set is invalid');
632
- }
633
- const artifactIds = new Set();
634
- const artifactTargets = new Set();
635
- for (const item of plan.artifacts) {
636
- const artifact = asRecord(item);
637
- if (!artifact) {
638
- return planError('Firmware update plan artifact is invalid');
639
- }
640
- assertExactKeys(artifact, ['artifactId', 'role', 'target', 'url', 'container'], ['logicalName', 'expectedSize', 'expectedSha256', 'targetVersion']);
641
- const artifactId = assertBoundedString(artifact.artifactId, 'artifact id', 160);
642
- if (artifactIds.has(artifactId)) {
643
- return planError('Firmware update plan contains duplicate artifact ids');
644
- }
645
- artifactIds.add(artifactId);
646
- if (!FIRMWARE_UPDATE_PLAN_ROLES.has(artifact.role) ||
647
- !FIRMWARE_UPDATE_PLAN_TARGETS.has(artifact.target) ||
648
- !PLAN_CONTAINERS.has(artifact.container)) {
649
- return planError('Firmware update plan artifact contract is invalid');
650
- }
651
- artifactTargets.add(artifact.target);
652
- assertArtifactUrl(artifact.url, `Firmware artifact ${artifactId}`);
653
- if (artifact.logicalName !== undefined) {
654
- assertBoundedString(artifact.logicalName, 'logical name', 256);
655
- }
656
- if (artifact.expectedSize !== undefined &&
657
- (!Number.isSafeInteger(artifact.expectedSize) || artifact.expectedSize <= 0)) {
658
- return planError('Firmware update plan artifact size is invalid');
659
- }
660
- if (artifact.expectedSha256 !== undefined &&
661
- (typeof artifact.expectedSha256 !== 'string' ||
662
- !/^[a-f0-9]{64}$/u.test(artifact.expectedSha256))) {
663
- return planError('Firmware update plan artifact digest is invalid');
664
- }
665
- if (artifact.targetVersion !== undefined) {
666
- assertBoundedString(artifact.targetVersion, 'target version', 64);
667
- }
668
- }
669
- if (!Array.isArray(plan.targetsToUpdate) ||
670
- plan.targetsToUpdate.some(target => !FIRMWARE_UPDATE_PLAN_TARGETS.has(target)) ||
671
- new Set(plan.targetsToUpdate).size !== plan.targetsToUpdate.length ||
672
- plan.targetsToUpdate.length !== artifactTargets.size ||
673
- plan.targetsToUpdate.some(target => !artifactTargets.has(target))) {
674
- return planError('Firmware update plan targets are invalid');
675
- }
676
- const legacyTargets = new Set([
677
- 'firmware',
678
- 'ble',
679
- 'bootloader',
680
- 'resource',
681
- ]);
682
- const legacyOnlyTargets = new Set(['firmware', 'ble', 'bootloader']);
683
- if (((plan.executor === 'v2' || plan.executor === 'v3') &&
684
- plan.targetsToUpdate.some(target => !legacyTargets.has(target))) ||
685
- (plan.executor === 'v4' &&
686
- plan.targetsToUpdate.some(target => legacyOnlyTargets.has(target))) ||
687
- (plan.artifacts.length > 0 &&
688
- (plan.platform === 'native' || plan.platform === 'desktop') &&
689
- plan.deviceIdentity === 'unavailable')) {
690
- return planError('Firmware update plan executor contract is invalid');
691
- }
692
- const _a = plan, { planDigest } = _a, withoutDigest = __rest(_a, ["planDigest"]);
693
- if (digestFirmwareUpdatePlan(withoutDigest) !== planDigest) {
694
- return planError('Firmware update plan digest is invalid');
695
- }
696
- return plan;
697
- };
698
- const selectResourceUrl = ({ release, features, platform, }) => {
699
- const resource = asString(release.resource);
700
- const fullResource = asString(release.fullResource);
701
- const range = release.fullResourceRange;
702
- const currentVersion = getDeviceFirmwareVersion(features).join('.');
703
- const targetVersion = asVersion(release.version);
704
- if (platform === 'desktop' &&
705
- fullResource &&
706
- targetVersion &&
707
- Array.isArray(range) &&
708
- range.length === 2 &&
709
- typeof range[0] === 'string' &&
710
- typeof range[1] === 'string' &&
711
- semver__default["default"].valid(currentVersion) &&
712
- semver__default["default"].valid(targetVersion) &&
713
- semver__default["default"].valid(range[0]) &&
714
- semver__default["default"].valid(range[1]) &&
715
- semver__default["default"].lt(currentVersion, range[0]) &&
716
- semver__default["default"].gte(targetVersion, range[1])) {
717
- return fullResource;
718
- }
719
- return resource;
720
- };
721
- const getExecutor = (features) => {
722
- const deviceType = getDeviceType(features);
723
- if (deviceType === hdShared.EDeviceType.Pro2) {
724
- return 'v4';
725
- }
726
- if (deviceType === hdShared.EDeviceType.Pro &&
727
- semver__default["default"].gte(getDeviceBootloaderVersion(features).join('.'), '2.8.0')) {
728
- return 'v3';
729
- }
730
- return 'v2';
731
- };
732
- const buildProtocolV2Artifacts = (release) => {
733
- var _a;
734
- const components = asRecord(release.components);
735
- if (!components) {
736
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 release has no component set', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
737
- }
738
- const installOrder = Array.isArray(release.installOrder)
739
- ? release.installOrder.filter((key) => typeof key === 'string')
740
- : [];
741
- const componentKeys = [
742
- ...installOrder,
743
- ...Object.keys(components).filter(key => !installOrder.includes(key)),
744
- ];
745
- const artifacts = [];
746
- const targets = [];
747
- const componentTargets = new Set();
748
- for (const key of componentKeys) {
749
- const component = asRecord(components[key]);
750
- const targetName = (_a = asString(component === null || component === void 0 ? void 0 : component.target)) === null || _a === void 0 ? void 0 : _a.toUpperCase();
751
- if (targetName === 'ROMLOADER') {
752
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 ROMLOADER requires its dedicated loader flow', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
753
- }
754
- const target = targetName ? PROTOCOL_V2_TARGETS[targetName] : undefined;
755
- if (!component || !target) {
756
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} has an unsupported target`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
757
- }
758
- if (componentTargets.has(target)) {
759
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 component ${key} duplicates target ${target}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
760
- }
761
- componentTargets.add(target);
762
- 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({
763
- size: component.expectedSize,
764
- sha256: component.fingerprint,
765
- })), (asVersion(component.version) ? { targetVersion: asVersion(component.version) } : {})));
766
- targets.push(target);
767
- }
768
- const bundles = Array.isArray(release.resourceBundles) ? release.resourceBundles : [];
769
- const resourceBundleNames = new Set();
770
- for (const value of bundles) {
771
- const bundle = asRecord(value);
772
- const name = asString(bundle === null || bundle === void 0 ? void 0 : bundle.name);
773
- if (!bundle || !name) {
774
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource bundle is invalid', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
775
- }
776
- if (resourceBundleNames.has(name)) {
777
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource bundle duplicates name ${name}`, { firmwareUpdateCode: 'FirmwarePlanInvalid' });
778
- }
779
- resourceBundleNames.add(name);
780
- 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({
781
- size: bundle.expectedSize,
782
- sha256: bundle.fingerprint,
783
- })));
784
- }
785
- if (bundles.length > 0) {
786
- targets.push('resource');
787
- }
788
- return { artifacts, targets: [...new Set(targets)] };
789
- };
790
- const buildFirmwareUpdatePlan = ({ features, firmwareType, platform, firmware, ble, bootloader, }) => {
791
- var _a, _b, _c, _d, _e, _f, _g;
792
- const executor = getExecutor(features);
793
- let artifacts = [];
794
- let targetsToUpdate = [];
795
- const firmwareRelease = asRelease(firmware);
796
- if (executor === 'v4' && isUpgrade(firmware)) {
797
- const protocolV2 = buildProtocolV2Artifacts(firmwareRelease !== null && firmwareRelease !== void 0 ? firmwareRelease : {});
798
- artifacts = protocolV2.artifacts;
799
- targetsToUpdate = protocolV2.targets;
800
- }
801
- else {
802
- if (isUpgrade(bootloader)) {
803
- 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({
804
- size: (_b = asRelease(bootloader)) === null || _b === void 0 ? void 0 : _b.bootloaderExpectedSize,
805
- sha256: (_c = asRelease(bootloader)) === null || _c === void 0 ? void 0 : _c.bootloaderFingerprint,
806
- })), (asVersion((_d = asRelease(bootloader)) === null || _d === void 0 ? void 0 : _d.bootloaderVersion)
807
- ? {
808
- targetVersion: asVersion((_e = asRelease(bootloader)) === null || _e === void 0 ? void 0 : _e.bootloaderVersion),
809
- }
810
- : {})));
811
- }
812
- if (isUpgrade(firmware)) {
813
- if (!firmwareRelease) {
814
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware release is invalid', {
815
- firmwareUpdateCode: 'FirmwarePlanInvalid',
816
- });
817
- }
818
- artifacts.push(Object.assign(Object.assign({ artifactId: 'firmware', role: 'firmware', target: 'firmware', url: assertArtifactUrl(firmwareRelease.url, 'Firmware release'), container: 'raw' }, asIntegrity({
819
- size: firmwareRelease.expectedSize,
820
- sha256: firmwareRelease.fingerprint,
821
- })), (asVersion(firmwareRelease.version)
822
- ? { targetVersion: asVersion(firmwareRelease.version) }
823
- : {})));
824
- const resourceUrl = selectResourceUrl({
825
- release: firmwareRelease,
826
- features,
827
- platform,
828
- });
829
- if (resourceUrl) {
830
- artifacts.push(Object.assign({ artifactId: 'resource', role: 'resource', target: 'resource', url: assertArtifactUrl(resourceUrl, 'Firmware resource release'), container: 'zip' }, asIntegrity({
831
- size: resourceUrl === asString(firmwareRelease.fullResource)
832
- ? firmwareRelease.fullResourceExpectedSize
833
- : firmwareRelease.resourceExpectedSize,
834
- sha256: resourceUrl === asString(firmwareRelease.fullResource)
835
- ? firmwareRelease.fullResourceFingerprint
836
- : firmwareRelease.resourceFingerprint,
837
- })));
838
- }
839
- }
840
- if (isUpgrade(ble)) {
841
- const bleRelease = asRelease(ble);
842
- 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({
843
- size: bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.expectedSize,
844
- 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,
845
- })), (asVersion(bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.version)
846
- ? { targetVersion: asVersion(bleRelease === null || bleRelease === void 0 ? void 0 : bleRelease.version) }
847
- : {})));
848
- }
849
- targetsToUpdate = [...new Set(artifacts.map(artifact => artifact.target))];
850
- }
851
- const deviceIdentity = getDeviceUUID(features);
852
- if (artifacts.length > 0 &&
853
- (platform === 'native' || platform === 'desktop') &&
854
- !deviceIdentity) {
855
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Prepared firmware update requires a stable device identity', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
856
- }
857
- const planWithoutDigest = {
858
- schemaVersion: 2,
859
- executor,
860
- deviceIdentity: deviceIdentity || 'unavailable',
861
- deviceModel: String(getDeviceType(features)),
862
- firmwareType,
863
- platform,
864
- artifacts,
865
- targetsToUpdate,
866
- };
867
- return Object.assign(Object.assign({}, planWithoutDigest), { planDigest: digestFirmwareUpdatePlan(planWithoutDigest) });
868
- };
869
-
870
- const preparedPlanError = (message) => {
871
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
872
- firmwareUpdateCode: 'FirmwarePreparedPlanInvalid',
873
- });
874
- };
875
- const digestPreparedPlan = (plan) => digestFirmwareUpdateContract(plan);
876
- const assertOpaqueLeaseRef = (value) => {
877
- if (typeof value !== 'string' ||
878
- value.length === 0 ||
879
- value.length > 160 ||
880
- value.includes('/') ||
881
- value.includes('\\')) {
882
- return preparedPlanError('Firmware prepared plan leaseRef must be opaque');
883
- }
884
- return value;
885
- };
886
- const getFirmwareUpdateResourceName = (value) => {
887
- const normalized = typeof value === 'string' ? value.normalize('NFC') : undefined;
888
- const parts = normalized === null || normalized === void 0 ? void 0 : normalized.split('/');
889
- const resourceName = parts === null || parts === void 0 ? void 0 : parts.at(-1);
890
- if (typeof value !== 'string' ||
891
- value.length === 0 ||
892
- value.length > 512 ||
893
- value !== normalized ||
894
- value.startsWith('/') ||
895
- value.includes('\\') ||
896
- value.includes(':') ||
897
- [...value].some(char => {
898
- const code = char.charCodeAt(0);
899
- return code <= 0x1f || code === 0x7f;
900
- }) ||
901
- !(parts === null || parts === void 0 ? void 0 : parts.every(part => part.length > 0 &&
902
- part !== '.' &&
903
- part !== '..' &&
904
- !part.endsWith('.') &&
905
- !part.endsWith(' '))) ||
906
- !resourceName ||
907
- resourceName.length > 128) {
908
- return preparedPlanError('Firmware prepared plan entry name is invalid');
909
- }
910
- return resourceName;
911
- };
912
- const assertPreparedEntry = (value) => {
913
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
914
- return preparedPlanError('Firmware prepared plan entry must be an object');
915
- }
916
- const entry = value;
917
- if (Object.keys(entry).length !== 2 ||
918
- !Object.prototype.hasOwnProperty.call(entry, 'entryName') ||
919
- !Object.prototype.hasOwnProperty.call(entry, 'artifact')) {
920
- return preparedPlanError('Firmware prepared plan entry fields are invalid');
921
- }
922
- getFirmwareUpdateResourceName(entry.entryName);
923
- assertFirmwareArtifactReference(entry.artifact);
924
- return value;
925
- };
926
- const assertPreparedArtifacts = ({ plan, artifacts, }) => {
927
- if (artifacts.length !== plan.artifacts.length) {
928
- return preparedPlanError('Firmware prepared plan does not cover every artifact');
929
- }
930
- const inputs = new Map();
931
- for (const input of artifacts) {
932
- if (!input ||
933
- typeof input !== 'object' ||
934
- typeof input.artifactId !== 'string' ||
935
- inputs.has(input.artifactId)) {
936
- return preparedPlanError('Firmware prepared plan contains a duplicate artifact receipt');
937
- }
938
- inputs.set(input.artifactId, input);
939
- }
940
- return plan.artifacts.map(planArtifact => {
941
- var _a;
942
- const input = inputs.get(planArtifact.artifactId);
943
- if (!input) {
944
- return preparedPlanError('Firmware prepared plan artifact receipt is missing');
945
- }
946
- const artifact = assertFirmwareArtifactReference(input.artifact);
947
- if ((planArtifact.expectedSize !== undefined && artifact.size !== planArtifact.expectedSize) ||
948
- (planArtifact.expectedSha256 !== undefined &&
949
- artifact.sha256.toLowerCase() !== planArtifact.expectedSha256.toLowerCase())) {
950
- return preparedPlanError('Firmware prepared plan receipt does not match the update plan');
951
- }
952
- const materializedEntries = (_a = input.materializedEntries) === null || _a === void 0 ? void 0 : _a.map(value => {
953
- const entry = assertPreparedEntry(value);
954
- return {
955
- entryName: entry.entryName,
956
- artifact: Object.assign(Object.assign({}, entry.artifact), { sha256: entry.artifact.sha256.toLowerCase() }),
957
- };
958
- });
959
- if ((planArtifact.container === 'raw' && (materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length)) ||
960
- (planArtifact.container === 'zip' && !(materializedEntries === null || materializedEntries === void 0 ? void 0 : materializedEntries.length))) {
961
- return preparedPlanError('Firmware prepared plan materialization is incomplete');
962
- }
963
- if (materializedEntries &&
964
- new Set(materializedEntries.map(entry => getFirmwareUpdateResourceName(entry.entryName).toLowerCase())).size !== materializedEntries.length) {
965
- return preparedPlanError('Firmware prepared plan contains duplicate entry names');
966
- }
967
- 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 } : {}));
968
- });
969
- };
970
- const prepareFirmwareUpdatePlan = ({ plan: value, leaseRef, artifacts, }) => {
971
- const plan = assertFirmwareUpdatePlan(value);
972
- const planWithoutDigest = {
973
- schemaVersion: 2,
974
- planDigest: plan.planDigest,
975
- networkPolicy: 'forbid',
976
- executor: plan.executor,
977
- deviceIdentity: plan.deviceIdentity,
978
- deviceModel: plan.deviceModel,
979
- firmwareType: plan.firmwareType,
980
- platform: plan.platform,
981
- leaseRef: assertOpaqueLeaseRef(leaseRef),
982
- artifacts: assertPreparedArtifacts({ plan, artifacts }),
983
- targetsToUpdate: plan.targetsToUpdate,
984
- };
985
- return Object.assign(Object.assign({}, planWithoutDigest), { preparedPlanDigest: digestPreparedPlan(planWithoutDigest) });
986
- };
987
- const validateFirmwareUpdatePreparedPlan = (value) => {
988
- var _a, _b, _c;
989
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
990
- return preparedPlanError('Firmware prepared plan must be an object');
991
- }
992
- const preparedPlan = value;
993
- const exactKeys = [
994
- 'schemaVersion',
995
- 'preparedPlanDigest',
996
- 'planDigest',
997
- 'networkPolicy',
998
- 'executor',
999
- 'deviceIdentity',
1000
- 'deviceModel',
1001
- 'firmwareType',
1002
- 'platform',
1003
- 'leaseRef',
1004
- 'artifacts',
1005
- 'targetsToUpdate',
1006
- ];
1007
- if (Object.keys(value).length !== exactKeys.length ||
1008
- exactKeys.some(key => !Object.prototype.hasOwnProperty.call(value, key)) ||
1009
- preparedPlan.schemaVersion !== 2 ||
1010
- preparedPlan.networkPolicy !== 'forbid' ||
1011
- !/^[a-f0-9]{64}$/u.test(preparedPlan.planDigest) ||
1012
- !/^[a-f0-9]{64}$/u.test(preparedPlan.preparedPlanDigest) ||
1013
- !Array.isArray(preparedPlan.artifacts) ||
1014
- !Array.isArray(preparedPlan.targetsToUpdate) ||
1015
- (preparedPlan.executor !== 'v2' &&
1016
- preparedPlan.executor !== 'v3' &&
1017
- preparedPlan.executor !== 'v4') ||
1018
- (preparedPlan.platform !== 'native' &&
1019
- preparedPlan.platform !== 'desktop' &&
1020
- preparedPlan.platform !== 'ext' &&
1021
- preparedPlan.platform !== 'web' &&
1022
- preparedPlan.platform !== 'web-embed') ||
1023
- (preparedPlan.firmwareType !== 'universal' && preparedPlan.firmwareType !== 'bitcoinonly') ||
1024
- typeof preparedPlan.deviceIdentity !== 'string' ||
1025
- preparedPlan.deviceIdentity.length === 0 ||
1026
- typeof preparedPlan.deviceModel !== 'string' ||
1027
- preparedPlan.deviceModel.length === 0) {
1028
- return preparedPlanError('Firmware prepared plan header is invalid');
1029
- }
1030
- assertOpaqueLeaseRef(preparedPlan.leaseRef);
1031
- const artifactIds = new Set();
1032
- const artifactTargets = new Set();
1033
- for (const artifact of preparedPlan.artifacts) {
1034
- if (!artifact || typeof artifact !== 'object') {
1035
- return preparedPlanError('Firmware prepared plan artifact is invalid');
1036
- }
1037
- const artifactKeys = [
1038
- 'artifactId',
1039
- 'role',
1040
- 'target',
1041
- 'container',
1042
- 'artifact',
1043
- ...(artifact.logicalName !== undefined ? ['logicalName'] : []),
1044
- ...(artifact.targetVersion !== undefined ? ['targetVersion'] : []),
1045
- ...(artifact.materializedEntries !== undefined ? ['materializedEntries'] : []),
1046
- ];
1047
- if (typeof artifact.artifactId !== 'string' ||
1048
- artifact.artifactId.length === 0 ||
1049
- artifactIds.has(artifact.artifactId) ||
1050
- Object.keys(artifact).length !== artifactKeys.length ||
1051
- artifactKeys.some(key => !Object.prototype.hasOwnProperty.call(artifact, key)) ||
1052
- !FIRMWARE_UPDATE_PLAN_ROLES.has(artifact.role) ||
1053
- !FIRMWARE_UPDATE_PLAN_TARGETS.has(artifact.target) ||
1054
- (artifact.container !== 'raw' && artifact.container !== 'zip') ||
1055
- (artifact.logicalName !== undefined &&
1056
- (typeof artifact.logicalName !== 'string' || artifact.logicalName.length === 0)) ||
1057
- (artifact.targetVersion !== undefined &&
1058
- (typeof artifact.targetVersion !== 'string' || artifact.targetVersion.length === 0)) ||
1059
- (artifact.materializedEntries !== undefined &&
1060
- !Array.isArray(artifact.materializedEntries)) ||
1061
- (artifact.container === 'raw' && Boolean((_a = artifact.materializedEntries) === null || _a === void 0 ? void 0 : _a.length)) ||
1062
- (artifact.container === 'zip' && !((_b = artifact.materializedEntries) === null || _b === void 0 ? void 0 : _b.length))) {
1063
- return preparedPlanError('Firmware prepared plan artifact is invalid');
1064
- }
1065
- artifactIds.add(artifact.artifactId);
1066
- artifactTargets.add(artifact.target);
1067
- assertFirmwareArtifactReference(artifact.artifact);
1068
- (_c = artifact.materializedEntries) === null || _c === void 0 ? void 0 : _c.forEach(assertPreparedEntry);
1069
- }
1070
- if (preparedPlan.targetsToUpdate.some(target => !FIRMWARE_UPDATE_PLAN_TARGETS.has(target)) ||
1071
- new Set(preparedPlan.targetsToUpdate).size !== preparedPlan.targetsToUpdate.length ||
1072
- preparedPlan.targetsToUpdate.length !== artifactTargets.size ||
1073
- preparedPlan.targetsToUpdate.some(target => !artifactTargets.has(target))) {
1074
- return preparedPlanError('Firmware prepared plan targets are invalid');
1075
- }
1076
- const { preparedPlanDigest } = preparedPlan, withoutDigest = __rest(preparedPlan, ["preparedPlanDigest"]);
1077
- if (digestPreparedPlan(withoutDigest) !== preparedPlanDigest) {
1078
- return preparedPlanError('Firmware prepared plan digest is invalid');
1079
- }
1080
- return preparedPlan;
1081
- };
1082
- const sameArtifactReference = (first, second) => first.artifactRef === second.artifactRef &&
1083
- first.size === second.size &&
1084
- first.sha256.toLowerCase() === second.sha256.toLowerCase();
1085
- const assertFirmwareUpdatePreparedPlanBinding = ({ preparedPlan: value, executor, platform, deviceIdentity, scopeTargets, bindings, }) => {
1086
- var _a;
1087
- const preparedPlan = validateFirmwareUpdatePreparedPlan(value);
1088
- if (preparedPlan.executor !== executor ||
1089
- (platform !== undefined && preparedPlan.platform !== platform) ||
1090
- (deviceIdentity !== undefined && preparedPlan.deviceIdentity !== deviceIdentity)) {
1091
- return preparedPlanError('Firmware prepared plan executor binding is invalid');
1092
- }
1093
- const scope = new Set(scopeTargets);
1094
- const expectedBindings = [];
1095
- for (const artifact of preparedPlan.artifacts) {
1096
- if (scope.has(artifact.target)) {
1097
- if (artifact.container === 'zip') {
1098
- for (const entry of (_a = artifact.materializedEntries) !== null && _a !== void 0 ? _a : []) {
1099
- expectedBindings.push(Object.assign(Object.assign({ target: artifact.target }, (artifact.target === 'resource' && artifact.logicalName
1100
- ? { logicalName: artifact.logicalName }
1101
- : {})), { entryName: entry.entryName, artifact: entry.artifact }));
1102
- }
1103
- }
1104
- else {
1105
- expectedBindings.push(Object.assign(Object.assign({ target: artifact.target }, (artifact.target === 'resource' && artifact.logicalName
1106
- ? { logicalName: artifact.logicalName }
1107
- : {})), { artifact: artifact.artifact }));
1108
- }
1109
- }
1110
- }
1111
- if (expectedBindings.length !== bindings.length ||
1112
- expectedBindings.some(expected => {
1113
- const matching = bindings.filter(binding => binding.target === expected.target &&
1114
- binding.logicalName === expected.logicalName &&
1115
- binding.entryName === expected.entryName &&
1116
- sameArtifactReference(binding.artifact, expected.artifact));
1117
- return matching.length !== 1;
1118
- })) {
1119
- return preparedPlanError('Firmware prepared plan artifact binding is invalid');
1120
- }
1121
- return preparedPlan;
1122
- };
1123
-
1124
- const bindingError = (message) => {
1125
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, message, {
1126
- firmwareUpdateCode: 'FirmwareArtifactReaderInvalid',
1127
- });
1128
- };
1129
- class FirmwareHostBindingRegistry {
1130
- constructor() {
1131
- this.generation = 0;
1132
- }
1133
- register(binding) {
1134
- var _a;
1135
- if (!binding ||
1136
- typeof ((_a = binding.artifactReader) === null || _a === void 0 ? void 0 : _a.open) !== 'function' ||
1137
- typeof binding.artifactReader.read !== 'function' ||
1138
- typeof binding.artifactReader.close !== 'function') {
1139
- return bindingError('Firmware host binding is invalid');
1140
- }
1141
- this.generation += 1;
1142
- this.binding = binding;
1143
- return this.generation;
1144
- }
1145
- unregister(generation) {
1146
- if (generation !== undefined && generation !== this.generation) {
1147
- return false;
1148
- }
1149
- this.generation += 1;
1150
- this.binding = undefined;
1151
- return true;
1152
- }
1153
- getGeneration() {
1154
- return this.generation;
1155
- }
1156
- resolve(generation) {
1157
- if (!Number.isSafeInteger(generation) ||
1158
- generation <= 0 ||
1159
- generation !== this.generation ||
1160
- !this.binding) {
1161
- return bindingError(`Firmware host binding generation ${generation} is stale`);
1162
- }
1163
- const { binding } = this;
1164
- const assertCurrent = () => {
1165
- if (generation !== this.generation || binding !== this.binding) {
1166
- bindingError(`Firmware host binding generation ${generation} is stale`);
1167
- }
1168
- };
1169
- return {
1170
- artifactReader: {
1171
- open: (input) => __awaiter(this, void 0, void 0, function* () {
1172
- assertCurrent();
1173
- const opened = yield binding.artifactReader.open(input);
1174
- try {
1175
- assertCurrent();
1176
- }
1177
- catch (error) {
1178
- if (opened === null || opened === void 0 ? void 0 : opened.readerId) {
1179
- yield binding.artifactReader
1180
- .close({ readerId: opened.readerId })
1181
- .catch(() => undefined);
1182
- }
1183
- throw error;
1184
- }
1185
- return opened;
1186
- }),
1187
- read: (input) => __awaiter(this, void 0, void 0, function* () {
1188
- assertCurrent();
1189
- const result = yield binding.artifactReader.read(input);
1190
- assertCurrent();
1191
- return result;
1192
- }),
1193
- close: input => binding.artifactReader.close(input),
1194
- },
1195
- };
1196
- }
1197
- }
1198
- const firmwareHostBindingRegistry = new FirmwareHostBindingRegistry();
1199
- const registerFirmwareUpdateHostBinding = (binding) => firmwareHostBindingRegistry.register(binding);
1200
- const unregisterFirmwareUpdateHostBinding = (generation) => firmwareHostBindingRegistry.unregister(generation);
1201
- const getFirmwareUpdateHostBindingGeneration = () => firmwareHostBindingRegistry.getGeneration();
1202
- const resolveFirmwareUpdateHostBinding = (generation) => firmwareHostBindingRegistry.resolve(generation !== null && generation !== void 0 ? generation : Number.NaN);
1203
-
1204
90
  const callbackManager = new Map();
1205
91
  const generateCallbackId = () => `callback_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
1206
92
  const registerCallback = (id, callback) => {
@@ -1223,22 +109,15 @@ const inject = ({ call, cancel, dispose, eventEmitter, init, updateSettings, swi
1223
109
  }, removeAllListeners: type => {
1224
110
  eventEmitter.removeAllListeners(type);
1225
111
  }, init,
1226
- call, dispose: () => __awaiter(void 0, void 0, void 0, function* () {
1227
- unregisterFirmwareUpdateHostBinding();
1228
- yield dispose();
1229
- }), uiResponse,
112
+ call,
113
+ dispose,
114
+ uiResponse,
1230
115
  cancel,
1231
116
  updateSettings,
1232
117
  switchTransport }, createCoreApi(call));
1233
118
  return api;
1234
119
  };
1235
120
  const createCoreApi = (call) => ({
1236
- getFirmwareUpdateCapabilities,
1237
- registerFirmwareUpdateHostBinding,
1238
- unregisterFirmwareUpdateHostBinding,
1239
- getFirmwareUpdateHostBindingGeneration,
1240
- prepareFirmwareUpdatePlan,
1241
- validateFirmwareUpdatePreparedPlan,
1242
121
  getLogs: () => call({ method: 'getLogs' }),
1243
122
  clearSessionCache: params => call(Object.assign(Object.assign({}, params), { method: 'clearSessionCache' })),
1244
123
  searchDevices: params => call(Object.assign(Object.assign({}, params), { method: 'searchDevices' })),
@@ -1257,6 +136,7 @@ const createCoreApi = (call) => ({
1257
136
  checkFirmwareTypeAvailable: params => call(Object.assign(Object.assign({}, params), { method: 'checkFirmwareTypeAvailable' })),
1258
137
  cipherKeyValue: (connectId, deviceId, params) => call(Object.assign(Object.assign({}, params), { connectId, deviceId, method: 'cipherKeyValue' })),
1259
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' })),
1260
140
  preInitialize: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'preInitialize' })),
1261
141
  deviceBackup: connectId => call({ connectId, method: 'deviceBackup' }),
1262
142
  deviceChangePin: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceChangePin' })),
@@ -1399,10 +279,9 @@ const lowLevelInject = ({ call, cancel, dispose, eventEmitter, init, uiResponse,
1399
279
  const api = Object.assign({ addHardwareGlobalEventListener, removeAllListeners: type => {
1400
280
  eventEmitter.removeAllListeners(type);
1401
281
  }, init,
1402
- call, dispose: () => __awaiter(void 0, void 0, void 0, function* () {
1403
- unregisterFirmwareUpdateHostBinding();
1404
- yield dispose();
1405
- }), uiResponse,
282
+ call,
283
+ dispose,
284
+ uiResponse,
1406
285
  cancel,
1407
286
  updateSettings,
1408
287
  switchTransport, emit: () => { } }, createCoreApi(call));
@@ -1906,10 +785,7 @@ const topLevelInject = () => {
1906
785
  }, call }, createCoreApi(call)), { removeAllListeners: type => {
1907
786
  eventEmitter.removeAllListeners(type);
1908
787
  lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.removeAllListeners(type);
1909
- }, dispose: () => __awaiter(void 0, void 0, void 0, function* () {
1910
- unregisterFirmwareUpdateHostBinding();
1911
- yield (lowLevelApi === null || lowLevelApi === void 0 ? void 0 : lowLevelApi.dispose());
1912
- }), 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 }); } });
1913
789
  return api;
1914
790
  };
1915
791
 
@@ -2477,6 +1353,221 @@ function cleanupSdkInstance(sdkInstanceId) {
2477
1353
  }
2478
1354
  }
2479
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
+
2480
1571
  const HD_HARDENED = 0x80000000;
2481
1572
  const toHardened = (n) => (n | HD_HARDENED) >>> 0;
2482
1573
  const fromHardened = (n) => (n & ~HD_HARDENED) >>> 0;
@@ -27183,9 +26274,10 @@ var nested = {
27183
26274
  MessageType_DeviceStatus: 60603,
27184
26275
  MessageType_DevGetOnboardingStatus: 60604,
27185
26276
  MessageType_DevOnboardingStatus: 60605,
26277
+ MessageType_DeviceSessionGet: 60606,
27186
26278
  MessageType_DeviceSession: 60607,
27187
26279
  MessageType_DeviceSessionAskPin: 60608,
27188
- MessageType_DeviceSessionOpen: 60609,
26280
+ MessageType_DeviceSessionAskPassphrase: 60609,
27189
26281
  MessageType_FilesystemPermissionFix: 60800,
27190
26282
  MessageType_FilesystemPathInfo: 60801,
27191
26283
  MessageType_FilesystemPathInfoQuery: 60802,
@@ -27219,10 +26311,6 @@ var nested = {
27219
26311
  [
27220
26312
  309,
27221
26313
  312
27222
- ],
27223
- [
27224
- 60606,
27225
- 60606
27226
26314
  ]
27227
26315
  ]
27228
26316
  },
@@ -38255,6 +37343,33 @@ var nested = {
38255
37343
  }
38256
37344
  }
38257
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
+ },
38258
37373
  ViewAmount: {
38259
37374
  fields: {
38260
37375
  is_unlimited: {
@@ -39199,91 +38314,47 @@ var nested = {
39199
38314
  DeviceSessionError_Busy: 5
39200
38315
  }
39201
38316
  },
39202
- DeviceSessionResume: {
38317
+ DeviceSessionGet: {
39203
38318
  fields: {
39204
38319
  session_id: {
39205
- rule: "required",
39206
38320
  type: "bytes",
39207
38321
  id: 1
39208
38322
  }
39209
38323
  }
39210
38324
  },
39211
- DeviceSessionHostPassphrase: {
39212
- fields: {
39213
- passphrase: {
39214
- rule: "required",
39215
- type: "string",
39216
- id: 1
39217
- }
39218
- }
39219
- },
39220
- DeviceSessionPassphraseOnDevice: {
39221
- fields: {
39222
- }
39223
- },
39224
- DeviceSessionAttachPinOnDevice: {
39225
- fields: {
39226
- }
39227
- },
39228
- DeviceSessionSelect: {
39229
- oneofs: {
39230
- access: {
39231
- oneof: [
39232
- "host_passphrase",
39233
- "passphrase_on_device",
39234
- "attach_pin_on_device"
39235
- ]
39236
- }
39237
- },
38325
+ DeviceSession: {
39238
38326
  fields: {
39239
- host_passphrase: {
39240
- type: "DeviceSessionHostPassphrase",
38327
+ session_id: {
38328
+ type: "bytes",
39241
38329
  id: 1
39242
38330
  },
39243
- passphrase_on_device: {
39244
- type: "DeviceSessionPassphraseOnDevice",
38331
+ btc_test_address: {
38332
+ type: "string",
39245
38333
  id: 2
39246
- },
39247
- attach_pin_on_device: {
39248
- type: "DeviceSessionAttachPinOnDevice",
39249
- id: 3
39250
38334
  }
39251
38335
  }
39252
38336
  },
39253
- DeviceSessionOpen: {
39254
- oneofs: {
39255
- mode: {
39256
- oneof: [
39257
- "resume",
39258
- "select"
39259
- ]
39260
- }
39261
- },
39262
- fields: {
39263
- resume: {
39264
- type: "DeviceSessionResume",
39265
- id: 1
39266
- },
39267
- select: {
39268
- type: "DeviceSessionSelect",
39269
- id: 2
39270
- }
38337
+ DeviceSessionPinType: {
38338
+ values: {
38339
+ Any: 1,
38340
+ Main: 2,
38341
+ AttachToPin: 3
39271
38342
  }
39272
38343
  },
39273
- DeviceSession: {
38344
+ DeviceSessionAskPin: {
39274
38345
  fields: {
39275
- session_id: {
39276
- type: "bytes",
38346
+ type: {
38347
+ type: "DeviceSessionPinType",
39277
38348
  id: 1
39278
- },
39279
- btc_test_address: {
39280
- type: "string",
39281
- id: 2
39282
38349
  }
39283
38350
  }
39284
38351
  },
39285
- DeviceSessionAskPin: {
38352
+ DeviceSessionAskPassphrase: {
39286
38353
  fields: {
38354
+ passphrase: {
38355
+ type: "string",
38356
+ id: 1
38357
+ }
39287
38358
  }
39288
38359
  },
39289
38360
  DeviceSessionAskPin_FailureSubCodes: {
@@ -40458,19 +39529,9 @@ class DataManager {
40458
39529
  return enrichedData;
40459
39530
  }
40460
39531
  static load(settings) {
40461
- var _b;
40462
39532
  return __awaiter(this, void 0, void 0, function* () {
40463
39533
  this.settings = settings;
40464
- const manifestMode = (_b = settings.firmwareManifestMode) !== null && _b !== void 0 ? _b : (settings.fetchConfig ? 'sdk-managed' : undefined);
40465
- if (settings.preloadedConfig) {
40466
- this.applyRemoteConfig(settings.preloadedConfig);
40467
- Log$i.log('[DataConfig] Preloaded firmware config loaded');
40468
- return;
40469
- }
40470
- if (manifestMode === 'external-only') {
40471
- throw new Error('External firmware config snapshot is required');
40472
- }
40473
- if (manifestMode !== 'sdk-managed') {
39534
+ if (!settings.fetchConfig) {
40474
39535
  return;
40475
39536
  }
40476
39537
  const url = settings.preRelease
@@ -40478,50 +39539,57 @@ class DataManager {
40478
39539
  : 'https://data.onekey.so/config.json';
40479
39540
  const urlWithCache = `${url}?noCache=${getTimeStamp()}`;
40480
39541
  let data = null;
39542
+ let fetchMethod = 'none';
40481
39543
  if (settings.configFetcher) {
40482
- Log$i.debug('[DataConfig] Trying client configFetcher...');
39544
+ Log$i.debug('[DataConfig] Trying configFetcher (client-side fetcher)...');
40483
39545
  try {
40484
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
+ }
40485
39554
  }
40486
39555
  catch (e) {
40487
- Log$i.warn('[DataConfig] Client configFetcher failed:', e);
39556
+ Log$i.warn('[DataConfig] ConfigFetcher error, will fallback to axios:', e);
40488
39557
  }
40489
39558
  }
40490
39559
  if (!data) {
40491
- Log$i.debug('[DataConfig] Trying SDK-managed config request...');
39560
+ Log$i.debug('[DataConfig] Trying axios (SDK default fetcher)...');
40492
39561
  try {
40493
39562
  const response = yield axios__default["default"].get(urlWithCache, {
40494
39563
  timeout: 7000,
40495
39564
  });
40496
39565
  data = response.data;
40497
- Log$i.log('[DataConfig] SDK-managed config request succeeded');
39566
+ fetchMethod = 'axios';
39567
+ Log$i.log('[DataConfig] Axios fetch success');
40498
39568
  }
40499
39569
  catch (e) {
40500
- Log$i.warn('[DataConfig] SDK-managed config request failed:', e);
39570
+ Log$i.warn('[DataConfig] Axios fetch error:', e);
40501
39571
  }
40502
39572
  }
40503
39573
  if (data) {
40504
- 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
+ };
40505
39587
  }
40506
39588
  else {
40507
- 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');
40508
39590
  }
40509
39591
  });
40510
39592
  }
40511
- static applyRemoteConfig(data) {
40512
- this.deviceMap = {
40513
- [hdShared.EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
40514
- [hdShared.EDeviceType.Classic1s]: this.enrichFirmwareReleaseInfo(data.classic1s),
40515
- [hdShared.EDeviceType.ClassicPure]: this.enrichFirmwareReleaseInfo(data.classicpure),
40516
- [hdShared.EDeviceType.Mini]: this.enrichFirmwareReleaseInfo(data.mini),
40517
- [hdShared.EDeviceType.Touch]: this.enrichFirmwareReleaseInfo(data.touch),
40518
- [hdShared.EDeviceType.Pro]: this.enrichFirmwareReleaseInfo(data.pro),
40519
- [hdShared.EDeviceType.Pro2]: this.enrichFirmwareReleaseInfo(data.pro2),
40520
- };
40521
- this.assets = {
40522
- bridge: data.bridge,
40523
- };
40524
- }
40525
39593
  static updateEnv(newEnv) {
40526
39594
  if (this.settings) {
40527
39595
  const prevEnv = this.settings.env;
@@ -40973,15 +40041,6 @@ const LogBlockEvent = new Set([
40973
40041
  UI_RESPONSE.RECEIVE_PIN,
40974
40042
  UI_RESPONSE.RECEIVE_PASSPHRASE,
40975
40043
  ]);
40976
- const LogBlockMethod = new Set([
40977
- 'evmSignTypedData',
40978
- 'openWalletSession',
40979
- 'DeviceSessionOpen',
40980
- 'deviceUploadWallpaper',
40981
- 'uploadPortfolio',
40982
- 'fileWrite',
40983
- 'fileRead',
40984
- ]);
40985
40044
  function getLogBlockLabel(message) {
40986
40045
  if (!message || typeof message !== 'object')
40987
40046
  return undefined;
@@ -40990,10 +40049,7 @@ function getLogBlockLabel(message) {
40990
40049
  return type;
40991
40050
  }
40992
40051
  const methodName = method !== null && method !== void 0 ? method : payload === null || payload === void 0 ? void 0 : payload.method;
40993
- if (methodName && LogBlockMethod.has(methodName)) {
40994
- return methodName;
40995
- }
40996
- return undefined;
40052
+ return methodName;
40997
40053
  }
40998
40054
 
40999
40055
  function assertCompleteDeviceSession(message) {
@@ -41001,7 +40057,7 @@ function assertCompleteDeviceSession(message) {
41001
40057
  !message.session_id ||
41002
40058
  typeof message.btc_test_address !== 'string' ||
41003
40059
  !message.btc_test_address) {
41004
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'DeviceSessionOpen returned an incomplete DeviceSession response.');
40060
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'DeviceSessionGet returned an incomplete DeviceSession response.');
41005
40061
  }
41006
40062
  }
41007
40063
 
@@ -41017,16 +40073,29 @@ const negotiateEventlessWalletSession = (device) => __awaiter(void 0, void 0, vo
41017
40073
  eventless_wallet_session: true,
41018
40074
  });
41019
40075
  });
41020
- const openDeviceSession = (device, request) => __awaiter(void 0, void 0, void 0, function* () {
40076
+ const getDeviceSession = (device, request) => __awaiter(void 0, void 0, void 0, function* () {
41021
40077
  try {
41022
- return yield device.commands.typedCall('DeviceSessionOpen', 'DeviceSession', request);
40078
+ return yield device.commands.typedCall('DeviceSessionGet', 'DeviceSession', request);
41023
40079
  }
41024
40080
  catch (error) {
41025
40081
  if (!isDeviceLockedError(error)) {
41026
40082
  throw error;
41027
40083
  }
41028
- yield device.unlockDevice();
41029
- return device.commands.typedCall('DeviceSessionOpen', 'DeviceSession', request);
40084
+ yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main);
40085
+ return device.commands.typedCall('DeviceSessionGet', 'DeviceSession', request);
40086
+ }
40087
+ });
40088
+ const askDevicePassphrase = (device, passphrase) => __awaiter(void 0, void 0, void 0, function* () {
40089
+ const request = () => device.commands.typedCall('DeviceSessionAskPassphrase', 'Success', passphrase ? { passphrase } : {});
40090
+ try {
40091
+ return yield request();
40092
+ }
40093
+ catch (error) {
40094
+ if (!isDeviceLockedError(error)) {
40095
+ throw error;
40096
+ }
40097
+ yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main);
40098
+ return request();
41030
40099
  }
41031
40100
  });
41032
40101
  const selectDeviceSession = (device) => __awaiter(void 0, void 0, void 0, function* () {
@@ -41037,9 +40106,9 @@ const selectDeviceSession = (device) => __awaiter(void 0, void 0, void 0, functi
41037
40106
  reason: 'open-wallet',
41038
40107
  };
41039
40108
  const response = yield device.commands.promptPassphrase(Object.assign({ existsAttachPinUser }, metadata), { cancelDeviceOnReject: false });
41040
- const hostPassphrase = typeof response.passphrase === 'string' ? response.passphrase.normalize('NFKD') : undefined;
40109
+ const hasHostPassphrase = typeof response.passphrase === 'string' && response.passphrase.length > 0;
41041
40110
  const selections = [
41042
- !!hostPassphrase,
40111
+ hasHostPassphrase,
41043
40112
  response.passphraseOnDevice === true,
41044
40113
  response.attachPinOnDevice === true,
41045
40114
  ].filter(Boolean).length;
@@ -41051,21 +40120,23 @@ const selectDeviceSession = (device) => __awaiter(void 0, void 0, void 0, functi
41051
40120
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Attach PIN wallet selection is unavailable on this device.');
41052
40121
  }
41053
40122
  device.emit(DEVICE.ATTACH_PIN_ON_DEVICE, device, metadata);
41054
- return openDeviceSession(device, { select: { attach_pin_on_device: {} } });
40123
+ yield device.unlockDevice(hdTransport.DeviceSessionPinType.AttachToPin);
40124
+ return getDeviceSession(device, {});
41055
40125
  }
41056
- if (response.passphraseOnDevice) {
41057
- device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, metadata);
41058
- return openDeviceSession(device, { select: { passphrase_on_device: {} } });
40126
+ if (hasHostPassphrase) {
40127
+ yield askDevicePassphrase(device, response.passphrase);
40128
+ return getDeviceSession(device, {});
41059
40129
  }
41060
- return openDeviceSession(device, {
41061
- select: { host_passphrase: { passphrase: hostPassphrase } },
41062
- });
40130
+ device.emit(DEVICE.PASSPHRASE_ON_DEVICE, device, metadata);
40131
+ yield askDevicePassphrase(device);
40132
+ return getDeviceSession(device, {});
41063
40133
  });
41064
40134
  function getProtocolV2WalletSession(device, options) {
41065
40135
  var _a, _b, _c, _d, _e, _f;
41066
40136
  return __awaiter(this, void 0, void 0, function* () {
41067
40137
  if (options === null || options === void 0 ? void 0 : options.initSession) {
41068
40138
  device.clearInternalState();
40139
+ device.passphraseState = undefined;
41069
40140
  }
41070
40141
  yield negotiateEventlessWalletSession(device);
41071
40142
  if (options === null || options === void 0 ? void 0 : options.onlyMainPin) {
@@ -41075,7 +40146,7 @@ function getProtocolV2WalletSession(device, options) {
41075
40146
  ? undefined
41076
40147
  : (_a = options === null || options === void 0 ? void 0 : options.expectedPassphraseState) !== null && _a !== void 0 ? _a : device.passphraseState;
41077
40148
  if (((_b = device.features) === null || _b === void 0 ? void 0 : _b.unlocked) === false) {
41078
- yield device.unlockDevice();
40149
+ yield device.unlockDevice(hdTransport.DeviceSessionPinType.Main);
41079
40150
  }
41080
40151
  if ((options === null || options === void 0 ? void 0 : options.onlyMainPin) || device.getCurrentPassphraseProtection() === false) {
41081
40152
  return {
@@ -41090,7 +40161,7 @@ function getProtocolV2WalletSession(device, options) {
41090
40161
  let resumed = false;
41091
40162
  if (cachedSessionId && expectedPassphraseState) {
41092
40163
  try {
41093
- response = yield openDeviceSession(device, { resume: { session_id: cachedSessionId } });
40164
+ response = yield getDeviceSession(device, { session_id: cachedSessionId });
41094
40165
  resumed = true;
41095
40166
  }
41096
40167
  catch (error) {
@@ -41099,6 +40170,10 @@ function getProtocolV2WalletSession(device, options) {
41099
40170
  }
41100
40171
  }
41101
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
+ }
41102
40177
  response = yield selectDeviceSession(device);
41103
40178
  }
41104
40179
  const { message } = response;
@@ -41122,6 +40197,14 @@ function getProtocolV2WalletSession(device, options) {
41122
40197
  };
41123
40198
  });
41124
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
+ }
41125
40208
 
41126
40209
  const getSupportProtocolV1MessageSchema = (features) => {
41127
40210
  var _a;
@@ -41457,16 +40540,9 @@ const parseConnectSettings = (input = {}) => {
41457
40540
  if (input.fetchConfig) {
41458
40541
  settings.fetchConfig = input.fetchConfig;
41459
40542
  }
41460
- if (input.firmwareManifestMode === 'sdk-managed' ||
41461
- input.firmwareManifestMode === 'external-only') {
41462
- settings.firmwareManifestMode = input.firmwareManifestMode;
41463
- }
41464
40543
  if (input.configFetcher) {
41465
40544
  settings.configFetcher = input.configFetcher;
41466
40545
  }
41467
- if (input.preloadedConfig) {
41468
- settings.preloadedConfig = input.preloadedConfig;
41469
- }
41470
40546
  return settings;
41471
40547
  };
41472
40548
 
@@ -41529,7 +40605,8 @@ function checkNeedUpdateBootForClassicAndMini({ features, willUpdateFirmware, fi
41529
40605
  });
41530
40606
  }
41531
40607
  const INIT_DATA_CHUNK_SIZE$1 = 16 * 1024;
41532
- const readBootloaderLength = (chunk) => {
40608
+ function checkBootloaderLength(data) {
40609
+ const chunk = new Uint8Array(data.slice(0, Math.min(INIT_DATA_CHUNK_SIZE$1, data.byteLength)));
41533
40610
  const buffer = ByteBuffer__default["default"].wrap(chunk, undefined, undefined, true);
41534
40611
  buffer.LE();
41535
40612
  buffer.readByte();
@@ -41539,22 +40616,9 @@ const readBootloaderLength = (chunk) => {
41539
40616
  const hdrlen = buffer.readUint32();
41540
40617
  buffer.readUint32();
41541
40618
  const codelen = buffer.readUint32();
41542
- return hdrlen + codelen;
41543
- };
41544
- function checkBootloaderLength(data) {
41545
- if (data.byteLength < 16) {
41546
- return false;
41547
- }
41548
- const chunk = new Uint8Array(data.slice(0, Math.min(INIT_DATA_CHUNK_SIZE$1, data.byteLength)));
41549
- return readBootloaderLength(chunk) === data.byteLength;
40619
+ const bootloaderLength = hdrlen + codelen;
40620
+ return bootloaderLength === data.byteLength;
41550
40621
  }
41551
- const checkBootloaderSourceLength = (source) => __awaiter(void 0, void 0, void 0, function* () {
41552
- if (source.size < 16) {
41553
- return false;
41554
- }
41555
- const chunk = new Uint8Array(yield source.readAt(0, Math.min(INIT_DATA_CHUNK_SIZE$1, source.size)));
41556
- return readBootloaderLength(chunk) === source.size;
41557
- });
41558
40622
 
41559
40623
  const DEVICE_SETTINGS_SHARED_FIELDS = [
41560
40624
  'language',
@@ -42516,10 +41580,6 @@ TransportManager.reactNativeInit = false;
42516
41580
  TransportManager.protocolV1MessageSchema = 'v1CurrentSchema';
42517
41581
  TransportManager.plugin = null;
42518
41582
 
42519
- const MAX_DEBUG_ARRAY_ITEMS = 20;
42520
- const MAX_DEBUG_OBJECT_KEYS = 40;
42521
- const MAX_DEBUG_STRING_LENGTH = 512;
42522
- const MAX_DEBUG_DEPTH = 4;
42523
41583
  const HIGH_VOLUME_DEBUG_CALLS = new Set([
42524
41584
  'FilesystemFileRead',
42525
41585
  'FilesystemFileWrite',
@@ -42530,84 +41590,14 @@ const HIGH_VOLUME_DEBUG_CALLS = new Set([
42530
41590
  'FirmwareUpload',
42531
41591
  'ResourceAck',
42532
41592
  ]);
42533
- const SENSITIVE_DEBUG_CALLS = new Set(['DeviceSessionOpen']);
41593
+ const DEVICE_SESSION_CALLS = new Set([
41594
+ 'DeviceSessionGet',
41595
+ 'DeviceSessionAskPin',
41596
+ 'DeviceSessionAskPassphrase',
41597
+ ]);
42534
41598
  function shouldReduceDebugForCall(type) {
42535
41599
  return HIGH_VOLUME_DEBUG_CALLS.has(type);
42536
41600
  }
42537
- function shouldBlockDebugForCall(type) {
42538
- return SENSITIVE_DEBUG_CALLS.has(type);
42539
- }
42540
- function getBinaryByteLength(value) {
42541
- if (value instanceof ArrayBuffer) {
42542
- return value.byteLength;
42543
- }
42544
- if (ArrayBuffer.isView(value)) {
42545
- return value.byteLength;
42546
- }
42547
- if (typeof Blob !== 'undefined' && value instanceof Blob) {
42548
- return value.size;
42549
- }
42550
- return undefined;
42551
- }
42552
- function summarizeRedactedData(value) {
42553
- const byteLength = getBinaryByteLength(value);
42554
- if (byteLength !== undefined) {
42555
- return `[redacted data: ${byteLength} bytes]`;
42556
- }
42557
- if (typeof value === 'string') {
42558
- return `[redacted data: string length=${value.length}]`;
42559
- }
42560
- if (Array.isArray(value)) {
42561
- return `[redacted data: array length=${value.length}]`;
42562
- }
42563
- if (value && typeof value === 'object') {
42564
- return `[redacted data: object keys=${Object.keys(value).length}]`;
42565
- }
42566
- return `[redacted data: ${typeof value}]`;
42567
- }
42568
- function sanitizeDebugPayload(value, key = '', depth = 0) {
42569
- if (key === 'data' && value !== null && value !== undefined) {
42570
- return summarizeRedactedData(value);
42571
- }
42572
- if (key && /passphrase/i.test(key)) {
42573
- return '[redacted passphrase]';
42574
- }
42575
- const byteLength = getBinaryByteLength(value);
42576
- if (byteLength !== undefined) {
42577
- return `[binary: ${byteLength} bytes]`;
42578
- }
42579
- if (typeof value === 'string') {
42580
- return value.length > MAX_DEBUG_STRING_LENGTH
42581
- ? `${value.slice(0, MAX_DEBUG_STRING_LENGTH)}... (len=${value.length})`
42582
- : value;
42583
- }
42584
- if (!value || typeof value !== 'object') {
42585
- return value;
42586
- }
42587
- if (depth >= MAX_DEBUG_DEPTH) {
42588
- return Array.isArray(value)
42589
- ? `[array length=${value.length}]`
42590
- : `[object keys=${Object.keys(value).length}]`;
42591
- }
42592
- if (Array.isArray(value)) {
42593
- const items = value
42594
- .slice(0, MAX_DEBUG_ARRAY_ITEMS)
42595
- .map(item => sanitizeDebugPayload(item, key, depth + 1));
42596
- if (value.length > MAX_DEBUG_ARRAY_ITEMS) {
42597
- items.push(`... (${value.length - MAX_DEBUG_ARRAY_ITEMS} more)`);
42598
- }
42599
- return items;
42600
- }
42601
- const entries = Object.entries(value).slice(0, MAX_DEBUG_OBJECT_KEYS);
42602
- const sanitized = {};
42603
- entries.forEach(([entryKey, entryValue]) => {
42604
- sanitized[entryKey] = sanitizeDebugPayload(entryValue, entryKey, depth + 1);
42605
- });
42606
- if (Object.keys(value).length > MAX_DEBUG_OBJECT_KEYS) {
42607
- sanitized.__truncated__ = `${Object.keys(value).length - MAX_DEBUG_OBJECT_KEYS} more keys`;
42608
- }
42609
- return sanitized;
42610
- }
42611
41601
  const stripInteractiveAckTimeout = (options) => {
42612
41602
  if (!options)
42613
41603
  return options;
@@ -42778,16 +41768,16 @@ class DeviceCommands {
42778
41768
  const promise = this.transport.call(this.mainId, type, msg !== null && msg !== void 0 ? msg : {}, options);
42779
41769
  this.callPromise = promise;
42780
41770
  const res = yield promise;
42781
- if (res.type === 'Failure') {
42782
- LogCore.debug('[DeviceCommands] [call] Received', res.type, res.message);
42783
- }
42784
- else if (!shouldReduceDebug) {
41771
+ if (!shouldReduceDebug) {
42785
41772
  LogCore.debug('[DeviceCommands] [call] Received', res.type);
42786
41773
  }
42787
41774
  return res;
42788
41775
  }
42789
41776
  catch (error) {
42790
- LogCore.debug('[DeviceCommands] [call] Received error', error);
41777
+ LogCore.debug('[DeviceCommands] [call] Received error', {
41778
+ request: type,
41779
+ errorCode: error === null || error === void 0 ? void 0 : error.errorCode,
41780
+ });
42791
41781
  if (error.errorCode === hdShared.HardwareErrorCode.BleDeviceBondError) {
42792
41782
  return {
42793
41783
  type: 'BleDeviceBondError',
@@ -42806,9 +41796,6 @@ class DeviceCommands {
42806
41796
  catch (error) {
42807
41797
  }
42808
41798
  }
42809
- if (responseData) {
42810
- Log$f.debug('error response', responseData);
42811
- }
42812
41799
  if (responseError === 'device disconnected during action') {
42813
41800
  return { type: 'BridgeDeviceDisconnected', message: { error: responseError } };
42814
41801
  }
@@ -42830,29 +41817,6 @@ class DeviceCommands {
42830
41817
  if (this.disposed) {
42831
41818
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'typedCall: DeviceCommands already disposed');
42832
41819
  }
42833
- try {
42834
- const skipTypes = [
42835
- 'ButtonAck',
42836
- 'PinMatrixAck',
42837
- 'PassphraseAck',
42838
- 'Cancel',
42839
- 'DeviceSessionOpen',
42840
- 'BixinPinInputOnDevice',
42841
- 'FilesystemFileRead',
42842
- 'FilesystemFileWrite',
42843
- 'FileRead',
42844
- 'FileWrite',
42845
- 'EmmcFileRead',
42846
- 'EmmcFileWrite',
42847
- 'FirmwareUpload',
42848
- 'ResourceAck',
42849
- ];
42850
- if (!skipTypes.includes(type) && !shouldBlockDebugForCall(type) && msg) {
42851
- Log$f.debug('[DeviceCommands] [typedCall] Sending payload', type, sanitizeDebugPayload(msg));
42852
- }
42853
- }
42854
- catch (e) {
42855
- }
42856
41820
  const expectedTypes = Array.isArray(resType) ? resType : resType.split('|');
42857
41821
  const response = yield this._commonCall(type, msg, Object.assign(Object.assign({}, options), { expectedTypes: (_a = options === null || options === void 0 ? void 0 : options.expectedTypes) !== null && _a !== void 0 ? _a : expectedTypes }));
42858
41822
  try {
@@ -42862,14 +41826,11 @@ class DeviceCommands {
42862
41826
  Log$f.debug('DeviceCommands typedcall error: ', error);
42863
41827
  if (error instanceof hdShared.HardwareError) {
42864
41828
  if (error.errorCode === hdShared.HardwareErrorCode.ResponseUnexpectTypeError) {
42865
- if (!shouldBlockDebugForCall(type)) {
42866
- Log$f.debug('[DeviceCommands] [typedCall] Unexpected response type', {
42867
- request: type,
42868
- expected: resType,
42869
- received: response.type,
42870
- response: sanitizeDebugPayload(response.message),
42871
- });
42872
- }
41829
+ Log$f.debug('[DeviceCommands] [typedCall] Unexpected response type', {
41830
+ request: type,
41831
+ expected: resType,
41832
+ received: response.type,
41833
+ });
42873
41834
  if (error.message.indexOf('BridgeNetworkError') > -1) {
42874
41835
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BridgeNetworkError);
42875
41836
  }
@@ -42898,13 +41859,11 @@ class DeviceCommands {
42898
41859
  _filterCommonTypes(res, callType, options) {
42899
41860
  var _a;
42900
41861
  try {
42901
- if (shouldReduceDebugForCall(callType) || shouldBlockDebugForCall(callType)) {
42902
- }
42903
- else if (DataManager.getSettings('env') === 'react-native') {
42904
- Log$f.debug('_filterCommonTypes: ', JSON.stringify(sanitizeDebugPayload(res)));
42905
- }
42906
- else {
42907
- Log$f.debug('_filterCommonTypes: ', sanitizeDebugPayload(res));
41862
+ if (!shouldReduceDebugForCall(callType)) {
41863
+ Log$f.debug('_filterCommonTypes: ', {
41864
+ request: callType,
41865
+ response: res.type,
41866
+ });
42908
41867
  }
42909
41868
  }
42910
41869
  catch (error) {
@@ -42950,7 +41909,7 @@ class DeviceCommands {
42950
41909
  const isLegacyProtocolV2ActionCancelledFailure = this.device.isProtocolV2() &&
42951
41910
  /^(?:cancelled on device|confirm dismissed)$/i.test(normalizedMessage);
42952
41911
  const isLegacyProtocolV2LockedFailure = this.device.isProtocolV2() && /^device (?:is )?locked$/i.test(normalizedMessage);
42953
- if (callType === 'DeviceSessionOpen' &&
41912
+ if (DEVICE_SESSION_CALLS.has(callType) &&
42954
41913
  subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_InvalidSession) {
42955
41914
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WalletSessionInvalid, message, {
42956
41915
  failureCode: code,
@@ -42958,7 +41917,7 @@ class DeviceCommands {
42958
41917
  firmwareMessage: message,
42959
41918
  });
42960
41919
  }
42961
- else if (callType === 'DeviceSessionOpen' &&
41920
+ else if (DEVICE_SESSION_CALLS.has(callType) &&
42962
41921
  subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_UserCancelled) {
42963
41922
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, message, {
42964
41923
  failureCode: code,
@@ -42966,7 +41925,7 @@ class DeviceCommands {
42966
41925
  firmwareMessage: message,
42967
41926
  });
42968
41927
  }
42969
- else if (callType === 'DeviceSessionOpen' &&
41928
+ else if (DEVICE_SESSION_CALLS.has(callType) &&
42970
41929
  subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_AttachPinUnavailable) {
42971
41930
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckUnlockTypeError, message, {
42972
41931
  failureCode: code,
@@ -42974,7 +41933,7 @@ class DeviceCommands {
42974
41933
  firmwareMessage: message,
42975
41934
  });
42976
41935
  }
42977
- else if (callType === 'DeviceSessionOpen' &&
41936
+ else if (DEVICE_SESSION_CALLS.has(callType) &&
42978
41937
  subcode === hdTransport.DeviceSessionErrorCode.DeviceSessionError_PassphraseDisabled) {
42979
41938
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotOpenedPassphrase, message, {
42980
41939
  failureCode: code,
@@ -42982,6 +41941,23 @@ class DeviceCommands {
42982
41941
  firmwareMessage: message,
42983
41942
  });
42984
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
+ }
42985
41961
  else if (subcode === hdTransport.DeviceErrorCode.DeviceError_ActionCancelled ||
42986
41962
  isLegacyProtocolV2ActionCancelledFailure) {
42987
41963
  error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, message, {
@@ -43979,8 +42955,8 @@ class Device extends events.exports {
43979
42955
  deviceId,
43980
42956
  path: (_a = this.originalDescriptor) === null || _a === void 0 ? void 0 : _a.path,
43981
42957
  bleName,
43982
- name: bleName || label || `OneKey ${deviceType === null || deviceType === void 0 ? void 0 : deviceType.toUpperCase()}`,
43983
- label: label || 'OneKey',
42958
+ name: label || bleName || `OneKey ${deviceType === null || deviceType === void 0 ? void 0 : deviceType.toUpperCase()}`,
42959
+ label: label !== null && label !== void 0 ? label : '',
43984
42960
  mode: this.getMode(),
43985
42961
  features,
43986
42962
  state,
@@ -43993,6 +42969,10 @@ class Device extends events.exports {
43993
42969
  const env = DataManager.getSettings('env');
43994
42970
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
43995
42971
  if (DataManager.isBleConnect(env)) {
42972
+ if (this.hasDeviceAcquire() && this.commands && !this.commands.disposed) {
42973
+ resolve(true);
42974
+ return;
42975
+ }
43996
42976
  try {
43997
42977
  yield this.acquire(connectProtocol);
43998
42978
  resolve(true);
@@ -44573,11 +43553,26 @@ class Device extends events.exports {
44573
43553
  return this.updateProtocolV2Features(previousDeviceInfo, Object.assign(Object.assign({}, previousStatus), status));
44574
43554
  }
44575
43555
  markTransportDisconnected() {
43556
+ this.deviceAcquired = false;
44576
43557
  if (!this.isProtocolV2())
44577
43558
  return;
44578
43559
  this.protocolV2StateNeedsReload = true;
44579
43560
  this.clearPreInitialized();
44580
43561
  }
43562
+ invalidateAfterWipe() {
43563
+ const deviceId = this.getCurrentDeviceId();
43564
+ if (deviceId) {
43565
+ deviceWalletSessionStore.deleteDevice(deviceId);
43566
+ }
43567
+ if (this.isProtocolV2() && this.originalDescriptor.path !== deviceId) {
43568
+ deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
43569
+ this.protocolV2StateNeedsReload = true;
43570
+ }
43571
+ this.passphraseState = undefined;
43572
+ this.stateStore = new DeviceStateStore();
43573
+ this.clearPreInitialized();
43574
+ this.needReloadDevice = true;
43575
+ }
44581
43576
  markProtocolV2Reboot(rebootType) {
44582
43577
  if (!this.isProtocolV2())
44583
43578
  return;
@@ -44809,7 +43804,7 @@ class Device extends events.exports {
44809
43804
  isUsedHere() {
44810
43805
  const env = DataManager.getSettings('env');
44811
43806
  if (DataManager.isBleConnect(env)) {
44812
- return false;
43807
+ return this.deviceAcquired;
44813
43808
  }
44814
43809
  return this.isUsed() && this.originalDescriptor.session === this.mainId;
44815
43810
  }
@@ -44873,14 +43868,12 @@ class Device extends events.exports {
44873
43868
  },
44874
43869
  };
44875
43870
  }
44876
- unlockDevice() {
43871
+ unlockDevice(pinType = hdTransport.DeviceSessionPinType.Main) {
44877
43872
  var _a, _b, _c;
44878
43873
  return __awaiter(this, void 0, void 0, function* () {
44879
43874
  if (this.isProtocolV2()) {
44880
43875
  try {
44881
- yield this.commands.typedCall('DeviceSessionAskPin', 'Success', undefined, {
44882
- timeoutMs: 120000,
44883
- });
43876
+ yield this.commands.typedCall('DeviceSessionAskPin', 'Success', { type: pinType });
44884
43877
  }
44885
43878
  catch (error) {
44886
43879
  const errorText = error instanceof Error
@@ -45385,6 +44378,46 @@ class TestInitializeDeviceDuration extends BaseMethod {
45385
44378
  }
45386
44379
  }
45387
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
+
45388
44421
  const Log$c = getLogger(exports.LoggerNames.Core);
45389
44422
  const parseInitOptions$1 = (payload) => ({
45390
44423
  initSession: payload === null || payload === void 0 ? void 0 : payload.initSession,
@@ -45564,13 +44597,16 @@ class GetPassphraseState extends BaseMethod {
45564
44597
  }
45565
44598
  run() {
45566
44599
  return __awaiter(this, void 0, void 0, function* () {
45567
- if (this.device.isProtocolV2()) {
45568
- throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
45569
- }
45570
44600
  if (!this.device.features) {
45571
44601
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
45572
44602
  }
45573
- const { passphraseState } = yield getPassphraseStateWithRefreshDeviceInfo(this.device);
44603
+ const isProtocolV2 = this.device.isProtocolV2();
44604
+ const { passphraseState } = yield getPassphraseStateWithRefreshDeviceInfo(this.device, isProtocolV2
44605
+ ? {
44606
+ onlyMainPin: this.payload.useEmptyPassphrase === true,
44607
+ initSession: this.payload.initSession === true,
44608
+ }
44609
+ : undefined);
45574
44610
  const passphraseProtection = this.device.getCurrentPassphraseProtection();
45575
44611
  return Promise.resolve(passphraseProtection === true ? passphraseState : undefined);
45576
44612
  });
@@ -45770,12 +44806,6 @@ const requiredString = (value, name) => {
45770
44806
  }
45771
44807
  return value.trim();
45772
44808
  };
45773
- const optionalBoolean = (value, name) => {
45774
- if (value !== undefined && typeof value !== 'boolean') {
45775
- throw invalidParameter$1(`Parameter [${name}] must be a boolean.`);
45776
- }
45777
- return value;
45778
- };
45779
44809
  const wasResumed = (session) => !!session &&
45780
44810
  typeof session === 'object' &&
45781
44811
  'resumed' in session &&
@@ -45788,49 +44818,22 @@ const requireHiddenWalletResponse = (session) => {
45788
44818
  return Object.assign({ passphraseState: session.passphraseState }, forwardSessionId(session));
45789
44819
  };
45790
44820
  const normalizeParams = (payload) => {
45791
- if (payload.mode !== undefined) {
45792
- if (payload.mode !== 'standard' &&
45793
- payload.mode !== 'select-hidden' &&
45794
- payload.mode !== 'resume-hidden') {
45795
- throw invalidParameter$1('Parameter [mode] must be one of standard, select-hidden, or resume-hidden.');
45796
- }
45797
- if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
45798
- throw invalidParameter$1('Parameters [useEmptyPassphrase] and [initSession] cannot be used with [mode].');
45799
- }
45800
- if (payload.mode === 'standard' || payload.mode === 'select-hidden') {
45801
- if (payload.deviceId !== undefined || payload.passphraseState !== undefined) {
45802
- throw invalidParameter$1('Parameters [deviceId] and [passphraseState] are only allowed with mode [resume-hidden].');
45803
- }
45804
- return { mode: payload.mode };
45805
- }
45806
- return {
45807
- mode: 'resume-hidden',
45808
- deviceId: requiredString(payload.deviceId, 'deviceId'),
45809
- passphraseState: requiredString(payload.passphraseState, 'passphraseState'),
45810
- };
44821
+ if (payload.mode === undefined) {
44822
+ throw invalidParameter$1('Parameter [mode] is required.');
45811
44823
  }
45812
- const useEmptyPassphrase = optionalBoolean(payload.useEmptyPassphrase, 'useEmptyPassphrase');
45813
- const initSession = optionalBoolean(payload.initSession, 'initSession');
45814
- if (useEmptyPassphrase === true) {
45815
- 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.');
45816
44828
  }
45817
- if (initSession === true) {
45818
- const deviceId = payload.deviceId === undefined ? undefined : requiredString(payload.deviceId, 'deviceId');
45819
- const passphraseState = payload.passphraseState === undefined
45820
- ? undefined
45821
- : requiredString(payload.passphraseState, 'passphraseState');
45822
- return Object.assign({ mode: 'select-hidden' }, (passphraseState
45823
- ? {
45824
- legacySessionToClear: {
45825
- deviceId,
45826
- passphraseState,
45827
- },
45828
- }
45829
- : {}));
44829
+ if (payload.useEmptyPassphrase !== undefined || payload.initSession !== undefined) {
44830
+ throw invalidParameter$1('Legacy parameters [useEmptyPassphrase] and [initSession] are not supported by openWalletSession.');
45830
44831
  }
45831
- const hasWalletBinding = payload.deviceId !== undefined || payload.passphraseState !== undefined;
45832
- if (!hasWalletBinding) {
45833
- 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 };
45834
44837
  }
45835
44838
  return {
45836
44839
  mode: 'resume-hidden',
@@ -45851,29 +44854,17 @@ class OpenWalletSession extends BaseMethod {
45851
44854
  const isProtocolV2 = this.device.isProtocolV2();
45852
44855
  const state = yield this.device.getDeviceState({ refreshSections: ['status'] });
45853
44856
  let currentDeviceId = state.identity.deviceId;
45854
- const { legacySessionToClear } = this.params;
45855
44857
  const requireDeviceId = () => {
45856
44858
  if (!currentDeviceId) {
45857
44859
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed);
45858
44860
  }
45859
44861
  return currentDeviceId;
45860
44862
  };
45861
- const clearLegacySession = () => {
45862
- const deviceId = requireDeviceId();
45863
- if (legacySessionToClear &&
45864
- (!legacySessionToClear.deviceId || legacySessionToClear.deviceId === deviceId)) {
45865
- deviceWalletSessionStore.delete(deviceId, legacySessionToClear.passphraseState);
45866
- }
45867
- };
45868
44863
  const refreshProtocolV2DeviceId = () => __awaiter(this, void 0, void 0, function* () {
45869
44864
  const refreshedState = yield this.device.getDeviceState({ refreshSections: ['status'] });
45870
44865
  currentDeviceId = refreshedState.identity.deviceId;
45871
- clearLegacySession();
45872
44866
  return requireDeviceId();
45873
44867
  });
45874
- if (!isProtocolV2) {
45875
- clearLegacySession();
45876
- }
45877
44868
  const protocol = isProtocolV2 ? 'V2' : 'V1';
45878
44869
  if (this.params.mode === 'standard') {
45879
44870
  this.device.passphraseState = undefined;
@@ -46190,7 +45181,8 @@ class CheckAllFirmwareRelease extends BaseMethod {
46190
45181
  var _a, _b;
46191
45182
  return __awaiter(this, void 0, void 0, function* () {
46192
45183
  const { features } = this.device;
46193
- const { checkBridgeRelease, firmwareType: firmwareTypeParams, platform, } = this.payload;
45184
+ const { checkBridgeRelease, firmwareType: firmwareTypeParams } = this
45185
+ .payload;
46194
45186
  if (!features) {
46195
45187
  return Promise.resolve(null);
46196
45188
  }
@@ -46215,14 +45207,6 @@ class CheckAllFirmwareRelease extends BaseMethod {
46215
45207
  firmwareType,
46216
45208
  });
46217
45209
  const bleFirmwareReleaseInfo = getBleFirmwareReleaseInfo(features);
46218
- const firmwareUpdatePlan = buildFirmwareUpdatePlan({
46219
- features,
46220
- firmwareType,
46221
- platform: platform !== null && platform !== void 0 ? platform : 'web',
46222
- firmware: firmwareRelease,
46223
- ble: bleFirmwareReleaseInfo,
46224
- bootloader: bootloaderRelease,
46225
- });
46226
45210
  return {
46227
45211
  firmware: firmwareRelease,
46228
45212
  bootloader: bootloaderRelease,
@@ -46236,7 +45220,6 @@ class CheckAllFirmwareRelease extends BaseMethod {
46236
45220
  }
46237
45221
  : undefined,
46238
45222
  features,
46239
- firmwareUpdatePlan,
46240
45223
  };
46241
45224
  });
46242
45225
  }
@@ -46543,7 +45526,6 @@ class DeviceReset extends BaseMethod {
46543
45526
  }
46544
45527
 
46545
45528
  const LOCK_FREE_DEVICE_SETTINGS = new Set([
46546
- 'label',
46547
45529
  'language',
46548
45530
  'brightness',
46549
45531
  'haptic_feedback',
@@ -47010,9 +45992,11 @@ class DeviceWipe extends BaseMethod {
47010
45992
  const res = yield this.device.commands.typedCall('DeviceSettingsPageShow', 'Success', {
47011
45993
  page: hdTransport.DeviceSettingsPage.DeviceReset,
47012
45994
  });
45995
+ this.device.invalidateAfterWipe();
47013
45996
  return Promise.resolve(res.message);
47014
45997
  }
47015
45998
  const res = yield this.device.commands.typedCall('WipeDevice', 'Success');
45999
+ this.device.invalidateAfterWipe();
47016
46000
  return Promise.resolve(res.message);
47017
46001
  });
47018
46002
  }
@@ -47119,13 +46103,7 @@ const waitBleInstall = (updateType) => __awaiter(void 0, void 0, void 0, functio
47119
46103
  yield wait(10 * 1000);
47120
46104
  }
47121
46105
  });
47122
- const toArrayBuffer$1 = (payload) => {
47123
- if (payload instanceof ArrayBuffer) {
47124
- return payload;
47125
- }
47126
- return new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength).slice().buffer;
47127
- };
47128
- 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* () {
47129
46107
  var _a, _b;
47130
46108
  const deviceType = device.getCurrentDeviceType();
47131
46109
  if (DeviceModelToTypes.model_mini.includes(deviceType)) {
@@ -47139,15 +46117,15 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47139
46117
  Log$a.debug('supportUpgradeFileHeader:', supportUpgradeFileHeader);
47140
46118
  if (supportUpgradeFileHeader) {
47141
46119
  const HEADER_SIZE = 1024;
47142
- if (source.size < HEADER_SIZE) {
47143
- 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`);
47144
46122
  }
47145
46123
  Log$a.debug('Uploading firmware header:', {
47146
46124
  size: HEADER_SIZE,
47147
- totalSize: source.size,
46125
+ totalSize: payload.byteLength,
47148
46126
  });
47149
46127
  postProgressTip(device, 'UploadingFirmwareHeader', postMessage);
47150
- const header = new Uint8Array(yield source.readAt(0, HEADER_SIZE));
46128
+ const header = new Uint8Array(payload.slice(0, HEADER_SIZE));
47151
46129
  try {
47152
46130
  const headerRes = yield typedCall('UpgradeFileHeader', 'Success', {
47153
46131
  data: bytesToHex$1(header),
@@ -47177,7 +46155,6 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47177
46155
  postProgressMessage(device, 0, 'installingFirmware', postMessage);
47178
46156
  let updateResponse;
47179
46157
  try {
47180
- const payload = yield readFirmwareByteSourceFully(source);
47181
46158
  updateResponse = yield typedCall('FirmwareUpload', 'Success', {
47182
46159
  payload,
47183
46160
  });
@@ -47205,19 +46182,21 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47205
46182
  if (device.features) {
47206
46183
  const bootloaderVersion = getDeviceBootloaderVersion(device.features);
47207
46184
  if (semver__default["default"].gte(bootloaderVersion.join('.'), NEW_BOOT_UPRATE_FIRMWARE_VERSION)) {
47208
- const response = yield newTouchUpdateProcess(updateType, postMessage, device, source, rebootOnSuccess);
46185
+ const response = yield newTouchUpdateProcess(updateType, postMessage, device, {
46186
+ payload,
46187
+ }, rebootOnSuccess);
47209
46188
  return response.message;
47210
46189
  }
47211
46190
  }
47212
46191
  postConfirmationMessage(device);
47213
46192
  postProgressTip(device, 'ConfirmOnDevice', postMessage);
47214
- const length = source.size;
46193
+ const length = payload.byteLength;
47215
46194
  let response = yield typedCall('FirmwareErase', ['FirmwareRequest', 'Success'], { length });
47216
46195
  postProgressTip(device, 'FirmwareEraseSuccess', postMessage);
47217
46196
  while (response.type !== 'Success') {
47218
46197
  const start = response.message.offset;
47219
46198
  const end = response.message.offset + response.message.length;
47220
- const chunk = yield source.readAt(start, end - start);
46199
+ const chunk = payload.slice(start, end);
47221
46200
  if (start > 0) {
47222
46201
  postProgressMessage(device, Math.round((start / length) * 100), 'transferData', postMessage);
47223
46202
  }
@@ -47234,21 +46213,7 @@ const uploadFirmwareFromSource = (updateType, typedCall, postMessage, device, so
47234
46213
  }
47235
46214
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'uploadFirmware: unknown device model');
47236
46215
  });
47237
- const uploadFirmware = (updateType, typedCall, postMessage, device, { payload, rebootOnSuccess, }, isUpdateBootloader) => __awaiter(void 0, void 0, void 0, function* () {
47238
- const source = yield openFirmwareByteSource({
47239
- binary: toArrayBuffer$1(payload),
47240
- });
47241
- if (!source) {
47242
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'firmware payload is empty');
47243
- }
47244
- try {
47245
- return yield uploadFirmwareFromSource(updateType, typedCall, postMessage, device, source, rebootOnSuccess, isUpdateBootloader);
47246
- }
47247
- finally {
47248
- yield source.close();
47249
- }
47250
- });
47251
- 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* () {
47252
46217
  var _c, _d, _e, _f, _g;
47253
46218
  let typedCall = device.getCommands().typedCall.bind(device.getCommands());
47254
46219
  postProgressTip(device, 'StartTransferData', postMessage);
@@ -47256,13 +46221,13 @@ const newTouchUpdateProcess = (updateType, postMessage, device, source, rebootOn
47256
46221
  const env = DataManager.getSettings('env');
47257
46222
  const perPackageSize = DataManager.isBleConnect(env) ? 16 : 128;
47258
46223
  const chunkSize = 1024 * perPackageSize;
47259
- const totalChunks = Math.ceil(source.size / chunkSize);
46224
+ const totalChunks = Math.ceil(payload.byteLength / chunkSize);
47260
46225
  let offset = 0;
47261
46226
  for (let i = 0; i < totalChunks; i++) {
47262
46227
  const chunkStart = i * chunkSize;
47263
- const chunkEnd = Math.min(chunkStart + chunkSize, source.size);
46228
+ const chunkEnd = Math.min(chunkStart + chunkSize, payload.byteLength);
47264
46229
  const chunkLength = chunkEnd - chunkStart;
47265
- const chunk = yield source.readAt(chunkStart, chunkLength);
46230
+ const chunk = payload.slice(chunkStart, chunkEnd);
47266
46231
  const overwrite = i === 0;
47267
46232
  const progress = Math.round(((i + 1) / totalChunks) * 100);
47268
46233
  const writeRes = yield emmcFileWriteWithRetry(device, filePath, chunkLength, offset, chunk, overwrite, progress);
@@ -47430,44 +46395,6 @@ const updateResource = (typedCall, fileName, data, onConfirmAfter) => __awaiter(
47430
46395
  onConfirmAfter === null || onConfirmAfter === void 0 ? void 0 : onConfirmAfter();
47431
46396
  return processResourceRequest(typedCall, res, data);
47432
46397
  });
47433
- const updateResourceFromSource = (typedCall, fileName, source, onConfirmAfter) => __awaiter(void 0, void 0, void 0, function* () {
47434
- const initialLength = Math.min(INIT_DATA_CHUNK_SIZE, source.size);
47435
- const initialChunk = new Uint8Array(yield source.readAt(0, initialLength));
47436
- let response = yield typedCall('ResourceUpdate', ['ResourceRequest', 'Success'], {
47437
- file_name: fileName,
47438
- data_length: source.size,
47439
- initial_data_chunk: bytesToHex$1(initialChunk),
47440
- hash: bytesToHex$1(blake2s.blake2s(initialChunk)),
47441
- });
47442
- onConfirmAfter === null || onConfirmAfter === void 0 ? void 0 : onConfirmAfter();
47443
- while (response.type !== 'Success') {
47444
- const { offset, data_length: dataLength } = response.message;
47445
- if (!Number.isSafeInteger(offset) ||
47446
- offset === undefined ||
47447
- offset < 0 ||
47448
- !Number.isSafeInteger(dataLength) ||
47449
- dataLength === undefined ||
47450
- dataLength <= 0 ||
47451
- offset + dataLength > source.size) {
47452
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Device requested an invalid firmware resource range');
47453
- }
47454
- const chunk = new Uint8Array(yield source.readAt(offset, dataLength));
47455
- response = yield typedCall('ResourceAck', ['ResourceRequest', 'Success'], {
47456
- data_chunk: bytesToHex$1(chunk),
47457
- hash: bytesToHex$1(blake2s.blake2s(chunk)),
47458
- });
47459
- }
47460
- return response.message;
47461
- });
47462
- const updateResourcesFromSources = (typedCall, postMessage, device, entries) => __awaiter(void 0, void 0, void 0, function* () {
47463
- postProgressTip(device, 'UpdateSysResource', postMessage);
47464
- for (const [index, entry] of entries.entries()) {
47465
- yield updateResourceFromSource(typedCall, entry.entryName, entry.source);
47466
- postProgressMessage(device, Math.floor(((index + 1) / entries.length) * 100), 'installingFirmware', postMessage);
47467
- }
47468
- postProgressTip(device, 'UpdateSysResourceSuccess', postMessage);
47469
- return true;
47470
- });
47471
46398
  const updateResources = (typedCall, postMessage, device, source) => __awaiter(void 0, void 0, void 0, function* () {
47472
46399
  postProgressTip(device, 'UpdateSysResource', postMessage);
47473
46400
  const zipData = yield JSZip__default["default"].loadAsync(source);
@@ -47487,22 +46414,10 @@ const updateResources = (typedCall, postMessage, device, source) => __awaiter(vo
47487
46414
  postProgressTip(device, 'UpdateSysResourceSuccess', postMessage);
47488
46415
  return true;
47489
46416
  });
47490
- const updateBootloader = (typedCall, postMessage, device, data) => __awaiter(void 0, void 0, void 0, function* () {
47491
- const source = yield openFirmwareByteSource({ binary: data });
47492
- if (!source) {
47493
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'bootloader payload is empty');
47494
- }
47495
- try {
47496
- return yield updateBootloaderFromSource(typedCall, postMessage, device, source);
47497
- }
47498
- finally {
47499
- yield source.close();
47500
- }
47501
- });
47502
- 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* () {
47503
46418
  postProgressTip(device, 'UpdateBootloader', postMessage);
47504
46419
  postProgressMessage(device, Math.floor(0), 'installingFirmware', postMessage);
47505
- yield updateResourceFromSource(typedCall, 'bootloader.bin', source, () => {
46420
+ yield updateResource(typedCall, 'bootloader.bin', source, () => {
47506
46421
  postProcessingMessage('resource', postMessage);
47507
46422
  });
47508
46423
  postProgressMessage(device, Math.floor(100), 'installingFirmware', postMessage);
@@ -47868,32 +46783,6 @@ class FirmwareUpdateBaseMethod extends BaseMethod {
47868
46783
  return totalSize !== undefined ? (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + payload.byteLength : 0;
47869
46784
  });
47870
46785
  }
47871
- emmcCommonUpdateProcessFromSource({ source, filePath, processedSize, totalSize, }) {
47872
- return __awaiter(this, void 0, void 0, function* () {
47873
- if (!filePath.startsWith('0:')) {
47874
- throw new Error('filePath must start with 0:');
47875
- }
47876
- const env = DataManager.getSettings('env');
47877
- const chunkSize = 1024 * (DataManager.isBleConnect(env) ? 16 : 128);
47878
- yield writeFirmwareByteSource({
47879
- source,
47880
- chunkSize,
47881
- write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
47882
- const progress = totalSize !== undefined && processedSize !== undefined
47883
- ? Math.min(Math.ceil(((processedSize + sourceOffset + length) / totalSize) * 100), 99)
47884
- : Math.min(Math.ceil(((sourceOffset + length) / source.size) * 100), 99);
47885
- const writeRes = yield this.emmcFileWriteWithRetry(filePath, length, sourceOffset, data, first, progress);
47886
- if (!writeRes) {
47887
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
47888
- }
47889
- const processedBytes = Number(writeRes.message.processed_byte);
47890
- this.postProgressMessage(progress, 'transferData');
47891
- return Number.isFinite(processedBytes) ? processedBytes : length;
47892
- }),
47893
- });
47894
- return totalSize !== undefined ? (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + source.size : 0;
47895
- });
47896
- }
47897
46786
  emmcFileWriteWithRetry(filePath, chunkLength, offset, chunk, overwrite, progress) {
47898
46787
  var _a, _b, _c, _d, _e, _f, _g, _h;
47899
46788
  return __awaiter(this, void 0, void 0, function* () {
@@ -47998,44 +46887,10 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
47998
46887
  return true;
47999
46888
  });
48000
46889
  }
48001
- updateBootloaderWithEmmcFileWriteFromSource(_device, source) {
48002
- return __awaiter(this, void 0, void 0, function* () {
48003
- const filePath = '0:boot/bootloader.bin';
48004
- this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
48005
- yield this.emmcCommonUpdateProcessFromSource({
48006
- source,
48007
- filePath,
48008
- });
48009
- this.postTipMessage(exports.FirmwareUpdateTipMessage.ConfirmOnDevice);
48010
- yield this.reboot(hdTransport.RebootType.Normal);
48011
- this.postTipMessage(exports.FirmwareUpdateTipMessage.UpdateBootloaderSuccess);
48012
- return true;
48013
- });
48014
- }
48015
- updateTouchBootloader({ device, features, firmwareType, binary: preparedBinary, source: preparedSource, }) {
46890
+ updateTouchBootloader({ device, features, firmwareType, }) {
48016
46891
  return __awaiter(this, void 0, void 0, function* () {
48017
- if (preparedSource) {
48018
- if (!(yield checkBootloaderSourceLength(preparedSource))) {
48019
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CheckDownloadFileError);
48020
- }
48021
- if (features && device.isBootloader()) {
48022
- this.postTipMessage(exports.FirmwareUpdateTipMessage.UpdateBootloader);
48023
- const result = yield this.updateBootloaderWithEmmcFileWriteFromSource(device, preparedSource);
48024
- return result;
48025
- }
48026
- if (features && !device.isBootloader()) {
48027
- yield updateBootloaderFromSource(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, preparedSource);
48028
- return true;
48029
- }
48030
- }
48031
- let binary = preparedBinary;
46892
+ let { binary } = this.payload;
48032
46893
  if (!binary) {
48033
- if (DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48034
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Bootloader must be prepared by the external firmware host', {
48035
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48036
- artifactName: 'bootloader',
48037
- });
48038
- }
48039
46894
  this.postTipMessage(exports.FirmwareUpdateTipMessage.CheckLatestUiResource);
48040
46895
  const resourceUrl = features
48041
46896
  ? DataManager.getBootloaderResource(features, firmwareType)
@@ -48049,13 +46904,12 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
48049
46904
  }
48050
46905
  }
48051
46906
  }
48052
- if (!binary || !checkBootloaderLength(binary)) {
46907
+ if (!checkBootloaderLength(binary)) {
48053
46908
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CheckDownloadFileError);
48054
46909
  }
48055
46910
  if (features && device.isBootloader()) {
48056
46911
  this.postTipMessage(exports.FirmwareUpdateTipMessage.UpdateBootloader);
48057
- const result = yield this.updateBootloaderWithEmmcFileWrite(device, binary);
48058
- return result;
46912
+ return this.updateBootloaderWithEmmcFileWrite(device, binary);
48059
46913
  }
48060
46914
  if (features && !device.isBootloader()) {
48061
46915
  yield updateBootloader(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, binary);
@@ -48064,63 +46918,16 @@ class DeviceUpdateBootloader extends FirmwareUpdateBaseMethod {
48064
46918
  });
48065
46919
  }
48066
46920
  run() {
48067
- var _a, _b, _c;
46921
+ var _a;
48068
46922
  return __awaiter(this, void 0, void 0, function* () {
48069
46923
  const { device } = this;
48070
46924
  const { features } = device;
48071
46925
  const payload = this.payload;
48072
- const hostBinding = payload.artifact
48073
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
48074
- : undefined;
48075
- 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 });
48076
- if (payload.artifact) {
48077
- assertFirmwareUpdatePreparedPlanBinding({
48078
- preparedPlan: payload.preparedPlan,
48079
- executor: 'v2',
48080
- scopeTargets: ['bootloader'],
48081
- bindings: [
48082
- {
48083
- target: 'bootloader',
48084
- artifact: payload.artifact,
48085
- },
48086
- ],
48087
- });
48088
- const source = yield openFirmwareByteSource({
48089
- artifact: payload.artifact,
48090
- reader: executionParams.artifactReader,
48091
- });
48092
- if (!source) {
48093
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Bootloader artifact is not prepared');
48094
- }
48095
- try {
48096
- const deviceType = device.getCurrentDeviceType();
48097
- const deviceFirmwareType = device.getCurrentFirmwareType();
48098
- const firmwareType = (_b = payload.firmwareType) !== null && _b !== void 0 ? _b : deviceFirmwareType;
48099
- if (DeviceModelToTypes.model_touch.includes(deviceType)) {
48100
- return yield this.updateTouchBootloader({
48101
- device,
48102
- features,
48103
- firmwareType,
48104
- source,
48105
- });
48106
- }
48107
- return true;
48108
- }
48109
- finally {
48110
- yield source.close();
48111
- }
48112
- }
48113
- const { binary } = payload;
48114
46926
  const deviceType = device.getCurrentDeviceType();
48115
46927
  const deviceFirmwareType = device.getCurrentFirmwareType();
48116
- const firmwareType = (_c = payload.firmwareType) !== null && _c !== void 0 ? _c : deviceFirmwareType;
46928
+ const firmwareType = (_a = payload.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
48117
46929
  if (DeviceModelToTypes.model_touch.includes(deviceType)) {
48118
- return this.updateTouchBootloader({
48119
- device,
48120
- features,
48121
- firmwareType,
48122
- binary,
48123
- });
46930
+ return this.updateTouchBootloader({ device, features, firmwareType });
48124
46931
  }
48125
46932
  return Promise.resolve(true);
48126
46933
  });
@@ -48401,12 +47208,6 @@ const normalizeFirmwareBinary = (binary) => {
48401
47208
  }
48402
47209
  return normalized.buffer;
48403
47210
  };
48404
- const toArrayBuffer = (binary) => {
48405
- if (binary instanceof ArrayBuffer) {
48406
- return binary;
48407
- }
48408
- return new Uint8Array(binary.buffer, binary.byteOffset, binary.byteLength).slice().buffer;
48409
- };
48410
47211
  class FirmwareUpdateV2 extends BaseMethod {
48411
47212
  constructor() {
48412
47213
  super(...arguments);
@@ -48421,7 +47222,6 @@ class FirmwareUpdateV2 extends BaseMethod {
48421
47222
  };
48422
47223
  }
48423
47224
  init() {
48424
- var _a;
48425
47225
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
48426
47226
  this.requireDeviceMode = [];
48427
47227
  this.useDevicePassphraseState = false;
@@ -48448,28 +47248,6 @@ class FirmwareUpdateV2 extends BaseMethod {
48448
47248
  if ('binary' in payload) {
48449
47249
  this.params = Object.assign(Object.assign({}, this.params), { binary: payload.binary });
48450
47250
  }
48451
- if ('artifact' in payload) {
48452
- const hostBinding = resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration);
48453
- const target = payload.isUpdateBootloader ? 'bootloader' : payload.updateType;
48454
- const resourceBindings = [
48455
- ...(payload.resourceArtifact
48456
- ? [{ target: 'resource', artifact: payload.resourceArtifact }]
48457
- : []),
48458
- ...((_a = payload.resourceEntries) !== null && _a !== void 0 ? _a : []).map((entry) => ({
48459
- target: 'resource',
48460
- entryName: entry.entryName,
48461
- artifact: entry.artifact,
48462
- })),
48463
- ];
48464
- assertFirmwareUpdatePreparedPlanBinding({
48465
- preparedPlan: payload.preparedPlan,
48466
- executor: 'v2',
48467
- platform: payload.platform,
48468
- scopeTargets: [target, ...(target === 'firmware' ? ['resource'] : [])],
48469
- bindings: [{ target, artifact: payload.artifact }, ...resourceBindings],
48470
- });
48471
- this.params = Object.assign(Object.assign({}, this.params), { preparedPlan: payload.preparedPlan, artifact: payload.artifact, resourceArtifact: payload.resourceArtifact, resourceEntries: payload.resourceEntries, artifactReader: hostBinding.artifactReader });
48472
- }
48473
47251
  }
48474
47252
  _promptDeviceInBootloaderForWebDevice() {
48475
47253
  return __awaiter(this, void 0, void 0, function* () {
@@ -48609,7 +47387,7 @@ class FirmwareUpdateV2 extends BaseMethod {
48609
47387
  }
48610
47388
  }
48611
47389
  run() {
48612
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
47390
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
48613
47391
  return __awaiter(this, void 0, void 0, function* () {
48614
47392
  const { device, params } = this;
48615
47393
  const { features, commands } = device;
@@ -48620,177 +47398,101 @@ class FirmwareUpdateV2 extends BaseMethod {
48620
47398
  const deviceFirmwareType = device.getCurrentFirmwareType();
48621
47399
  const firmwareType = (_a = params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
48622
47400
  this.checkVersionForCopyTouchResource(features, firmwareType);
48623
- let preparedSource;
48624
- try {
48625
- const acquireFirmwareSource = () => __awaiter(this, void 0, void 0, function* () {
48626
- var _k;
48627
- try {
48628
- if (preparedSource) {
48629
- return preparedSource;
48630
- }
48631
- if (params.binary !== undefined) {
48632
- const binary = normalizeFirmwareBinary(params.binary);
48633
- if (!binary) {
48634
- throw new Error('firmware binary is empty or invalid');
48635
- }
48636
- const source = yield openFirmwareByteSource({
48637
- binary: toArrayBuffer(binary),
48638
- });
48639
- if (!source) {
48640
- throw new Error('firmware binary is empty or invalid');
48641
- }
48642
- preparedSource = source;
48643
- return source;
48644
- }
48645
- if (params.artifact) {
48646
- const source = yield openFirmwareByteSource({
48647
- artifact: params.artifact,
48648
- reader: params.artifactReader,
48649
- });
48650
- if (!source) {
48651
- throw new Error('firmware artifact is not prepared');
48652
- }
48653
- preparedSource = source;
48654
- return source;
48655
- }
48656
- if (!device.features) {
48657
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'no features found for this device');
48658
- }
48659
- if (params.artifactReader ||
48660
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48661
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware must be prepared by the external firmware host', {
48662
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48663
- artifactName: 'firmware',
48664
- });
48665
- }
48666
- this.postTipMessage('DownloadFirmware');
48667
- const firmware = yield getBinary({
48668
- features: device.features,
48669
- version: params.version,
48670
- updateType: params.updateType,
48671
- isUpdateBootloader: params.isUpdateBootloader,
48672
- firmwareType,
48673
- requestOptions: FIRMWARE_DOWNLOAD_REQUEST_OPTIONS,
48674
- });
48675
- const binary = normalizeFirmwareBinary(firmware.binary);
48676
- if (!binary) {
48677
- throw new Error('downloaded firmware binary is empty or invalid');
48678
- }
48679
- const source = yield openFirmwareByteSource({
48680
- binary: toArrayBuffer(binary),
48681
- });
48682
- if (!source) {
48683
- 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');
48684
47412
  }
48685
- preparedSource = source;
48686
- this.postTipMessage('DownloadFirmwareSuccess');
48687
- return source;
47413
+ return preparedBinary;
48688
47414
  }
48689
- catch (err) {
48690
- 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');
48691
47417
  }
48692
- });
48693
- if (!device.isBootloader() && features) {
48694
- const serialNo = device.getCurrentSerialNo();
48695
- if (this.isEnteredManuallyBoot()) {
48696
- 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');
48697
47430
  }
48698
- yield acquireFirmwareSource();
48699
- if (this.isSupportResourceUpdate(params.updateType)) {
48700
- this.postTipMessage('CheckLatestUiResource');
48701
- const resourceUrl = DataManager.getSysResourcesLatestRelease({
48702
- features,
48703
- forcedUpdateRes: params.forcedUpdateRes,
48704
- firmwareType,
48705
- });
48706
- if (resourceUrl) {
48707
- this.postTipMessage('DownloadLatestUiResource');
48708
- if ((_b = params.resourceEntries) === null || _b === void 0 ? void 0 : _b.length) {
48709
- const sources = [];
48710
- try {
48711
- for (const entry of params.resourceEntries) {
48712
- const resourceName = getFirmwareUpdateResourceName(entry.entryName);
48713
- const source = yield openFirmwareByteSource({
48714
- artifact: entry.artifact,
48715
- reader: params.artifactReader,
48716
- });
48717
- if (!source) {
48718
- throw new Error('Firmware resource entry is not prepared');
48719
- }
48720
- sources.push({ entryName: resourceName, source });
48721
- }
48722
- yield updateResourcesFromSources(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, sources.map(entry => ({
48723
- entryName: entry.entryName,
48724
- source: entry.source,
48725
- })));
48726
- }
48727
- finally {
48728
- yield Promise.all(sources.map(entry => entry.source.close().catch(() => undefined)));
48729
- }
48730
- this.postTipMessage('DownloadLatestUiResourceSuccess');
48731
- }
48732
- else {
48733
- let resourceBinary;
48734
- if (params.resourceArtifact) {
48735
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware resource archive must be materialized into prepared entries', {
48736
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48737
- artifactName: 'resource',
48738
- });
48739
- }
48740
- else {
48741
- if (params.artifactReader ||
48742
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48743
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware resource must be prepared by the external firmware host', {
48744
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48745
- artifactName: 'resource',
48746
- });
48747
- }
48748
- resourceBinary = (yield getSysResourceBinary(resourceUrl)).binary;
48749
- }
48750
- this.postTipMessage('DownloadLatestUiResourceSuccess');
48751
- yield updateResources(this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, resourceBinary);
48752
- }
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);
48753
47456
  }
48754
47457
  }
48755
- (_d = (_c = this.device) === null || _c === void 0 ? void 0 : _c.commands) === null || _d === void 0 ? void 0 : _d.checkDisposed();
48756
- try {
48757
- this.postTipMessage('AutoRebootToBootloader');
48758
- const bootRes = yield commands.typedCall('DeviceBackToBoot', 'Success');
48759
- if (bootRes.type === 'CallMethodError') {
48760
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateAutoEnterBootFailure);
48761
- }
48762
- this.postTipMessage('GoToBootloaderSuccess');
48763
- this.checkDeviceToBootloader(this.payload.connectId);
48764
- if (DeviceModelToTypes.model_classic.includes(deviceType)) {
48765
- DevicePool.clearDeviceCache(serialNo);
48766
- }
48767
- delete DevicePool.devicesCache[''];
48768
- yield ((_e = this.checkPromise) === null || _e === void 0 ? void 0 : _e.promise);
48769
- this.checkPromise = null;
48770
- (_g = (_f = this.device) === null || _f === void 0 ? void 0 : _f.commands) === null || _g === void 0 ? void 0 : _g.checkDisposed();
48771
- const isTouch = DeviceModelToTypes.model_touch.includes(deviceType);
48772
- 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);
48773
47467
  }
48774
- catch (e) {
48775
- if (e instanceof hdShared.HardwareError) {
48776
- return Promise.reject(e);
48777
- }
48778
- console.log('auto go to bootloader mode failed: ', e);
48779
- 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);
48780
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);
48781
47479
  }
48782
- const source = yield acquireFirmwareSource();
48783
- (_j = (_h = this.device) === null || _h === void 0 ? void 0 : _h.commands) === null || _j === void 0 ? void 0 : _j.checkDisposed();
48784
- yield this.device.acquire();
48785
- const response = yield uploadFirmwareFromSource(params.updateType, this.device.getCommands().typedCall.bind(this.device.getCommands()), this.postMessage, device, source, true, params.isUpdateBootloader);
48786
- if (this.connectId) {
48787
- 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));
48788
47486
  }
48789
- return response;
48790
47487
  }
48791
- finally {
48792
- 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);
48793
47494
  }
47495
+ return response;
48794
47496
  });
48795
47497
  }
48796
47498
  }
@@ -48802,10 +47504,8 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48802
47504
  super(...arguments);
48803
47505
  this.checkPromise = null;
48804
47506
  this.isSwitchFirmware = false;
48805
- this.artifactSources = [];
48806
47507
  }
48807
47508
  init() {
48808
- var _a, _b, _c, _d, _e, _f;
48809
47509
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
48810
47510
  this.requireDeviceMode = [];
48811
47511
  this.useDevicePassphraseState = false;
@@ -48823,50 +47523,7 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48823
47523
  { name: 'firmwareType', type: 'string' },
48824
47524
  { name: 'platform', type: 'string' },
48825
47525
  ]);
48826
- const hostBinding = payload.artifacts || payload.preparedPlan
48827
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
48828
- : undefined;
48829
- if (hostBinding) {
48830
- assertFirmwareUpdatePreparedPlanBinding({
48831
- preparedPlan: payload.preparedPlan,
48832
- executor: 'v3',
48833
- platform: payload.platform,
48834
- scopeTargets: ['bootloader', 'firmware', 'resource', 'ble'],
48835
- bindings: [
48836
- ...(((_a = payload.artifacts) === null || _a === void 0 ? void 0 : _a.bootloader)
48837
- ? [
48838
- {
48839
- target: 'bootloader',
48840
- artifact: payload.artifacts.bootloader,
48841
- },
48842
- ]
48843
- : []),
48844
- ...(((_b = payload.artifacts) === null || _b === void 0 ? void 0 : _b.firmware)
48845
- ? [
48846
- {
48847
- target: 'firmware',
48848
- artifact: payload.artifacts.firmware,
48849
- },
48850
- ]
48851
- : []),
48852
- ...(((_c = payload.artifacts) === null || _c === void 0 ? void 0 : _c.ble)
48853
- ? [
48854
- {
48855
- target: 'ble',
48856
- artifact: payload.artifacts.ble,
48857
- },
48858
- ]
48859
- : []),
48860
- ...((_e = (_d = payload.artifacts) === null || _d === void 0 ? void 0 : _d.resourceEntries) !== null && _e !== void 0 ? _e : []).map((entry) => ({
48861
- target: 'resource',
48862
- entryName: entry.entryName,
48863
- artifact: entry.artifact,
48864
- })),
48865
- ],
48866
- });
48867
- }
48868
47526
  this.params = {
48869
- preparedPlan: payload.preparedPlan,
48870
47527
  bleBinary: payload.bleBinary,
48871
47528
  firmwareBinary: payload.firmwareBinary,
48872
47529
  forcedUpdateRes: payload.forcedUpdateRes,
@@ -48877,8 +47534,6 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48877
47534
  resourceBinary: payload.resourceBinary,
48878
47535
  firmwareType: payload.firmwareType,
48879
47536
  platform: payload.platform,
48880
- artifactReader: (_f = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _f !== void 0 ? _f : payload.artifactReader,
48881
- artifacts: payload.artifacts,
48882
47537
  };
48883
47538
  }
48884
47539
  run() {
@@ -48905,38 +47560,28 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48905
47560
  const firmwareType = (_b = this.params.firmwareType) !== null && _b !== void 0 ? _b : deviceFirmwareType;
48906
47561
  this.isSwitchFirmware = firmwareType !== deviceFirmwareType;
48907
47562
  let resourceBinary = null;
48908
- let resourceEntries = [];
48909
- let fwSources = [];
48910
- let bootloaderSource = null;
47563
+ let fwBinaryMap = [];
47564
+ let bootloaderBinary = null;
48911
47565
  try {
48912
47566
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
48913
- const resourceInput = yield this.prepareResourceInput(firmwareType);
48914
- resourceBinary = resourceInput.resourceBinary;
48915
- resourceEntries = resourceInput.resourceEntries;
48916
- fwSources = yield this.prepareFirmwareAndBleSources(firmwareType);
48917
- bootloaderSource = yield this.prepareBootloaderSource(firmwareType);
47567
+ resourceBinary = yield this.prepareResourceBinary(firmwareType);
47568
+ fwBinaryMap = yield this.prepareFirmwareAndBleBinary(firmwareType);
47569
+ bootloaderBinary = yield this.prepareBootloaderBinary(firmwareType);
48918
47570
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
48919
47571
  }
48920
47572
  catch (err) {
48921
- yield this.closeArtifactSources();
48922
47573
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_c = err.message) !== null && _c !== void 0 ? _c : err);
48923
47574
  }
48924
- if (!bootloaderSource && fwSources.length === 0) {
48925
- yield this.closeArtifactSources();
47575
+ if (!bootloaderBinary && fwBinaryMap.length === 0) {
48926
47576
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
48927
47577
  }
48928
- try {
48929
- yield this.enterBootloaderMode();
48930
- return yield this.executeUpdate({
48931
- resourceBinary,
48932
- resourceEntries,
48933
- fwSources,
48934
- bootloaderSource,
48935
- });
48936
- }
48937
- finally {
48938
- yield this.closeArtifactSources();
48939
- }
47578
+ yield this.enterBootloaderMode();
47579
+ const updateResult = yield this.executeUpdate({
47580
+ resourceBinary,
47581
+ fwBinaryMap,
47582
+ bootloaderBinary,
47583
+ });
47584
+ return updateResult;
48940
47585
  });
48941
47586
  }
48942
47587
  validateDeviceAndVersion(deviceType, bootloaderVersion) {
@@ -48950,93 +47595,31 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
48950
47595
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'bootloader version needs to be updated');
48951
47596
  }
48952
47597
  }
48953
- openArtifactSource(binary, artifact) {
48954
- return __awaiter(this, void 0, void 0, function* () {
48955
- const source = yield openFirmwareByteSource({
48956
- binary,
48957
- artifact,
48958
- reader: this.params.artifactReader,
48959
- });
48960
- if (source) {
48961
- this.artifactSources.push(source);
48962
- }
48963
- return source;
48964
- });
48965
- }
48966
- closeArtifactSources() {
48967
- return __awaiter(this, void 0, void 0, function* () {
48968
- const sources = this.artifactSources.splice(0);
48969
- yield Promise.all(sources.map(source => source.close().catch(() => undefined)));
48970
- });
48971
- }
48972
- assertSdkDownloadAllowed(artifactName) {
48973
- if (this.params.artifactReader ||
48974
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
48975
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `${artifactName} must be prepared by the external firmware host`, {
48976
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
48977
- artifactName,
48978
- });
48979
- }
48980
- }
48981
- prepareResourceInput(firmwareType) {
48982
- var _a;
47598
+ prepareResourceBinary(firmwareType) {
48983
47599
  return __awaiter(this, void 0, void 0, function* () {
48984
- const preparedEntries = (_a = this.params.artifacts) === null || _a === void 0 ? void 0 : _a.resourceEntries;
48985
- if ((preparedEntries === null || preparedEntries === void 0 ? void 0 : preparedEntries.length) && this.params.resourceBinary) {
48986
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware resource input must not contain both archive binary and prepared entries');
48987
- }
48988
- if (preparedEntries === null || preparedEntries === void 0 ? void 0 : preparedEntries.length) {
48989
- const resourceEntries = [];
48990
- for (const entry of preparedEntries) {
48991
- const resourceName = getFirmwareUpdateResourceName(entry.entryName);
48992
- const source = yield this.openArtifactSource(undefined, entry.artifact);
48993
- if (!source) {
48994
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Firmware resource entry ${entry.entryName} is not prepared`);
48995
- }
48996
- resourceEntries.push({ entryName: resourceName, source });
48997
- }
48998
- return {
48999
- resourceBinary: null,
49000
- resourceEntries,
49001
- };
49002
- }
49003
47600
  if (this.params.resourceBinary) {
49004
- return {
49005
- resourceBinary: this.params.resourceBinary,
49006
- resourceEntries: [],
49007
- };
47601
+ return this.params.resourceBinary;
49008
47602
  }
49009
47603
  const { features } = this.device;
49010
- if (!features) {
49011
- return {
49012
- resourceBinary: null,
49013
- resourceEntries: [],
49014
- };
49015
- }
47604
+ if (!features)
47605
+ return null;
49016
47606
  const resourceUrl = DataManager.getSysResourcesLatestRelease({
49017
47607
  features,
49018
47608
  forcedUpdateRes: this.params.forcedUpdateRes,
49019
47609
  firmwareType,
49020
47610
  });
49021
47611
  if (resourceUrl) {
49022
- this.assertSdkDownloadAllowed('resource');
49023
- return {
49024
- resourceBinary: (yield getSysResourceBinary(resourceUrl)).binary,
49025
- resourceEntries: [],
49026
- };
47612
+ const resource = (yield getSysResourceBinary(resourceUrl)).binary;
47613
+ return resource;
49027
47614
  }
49028
47615
  Log$6.warn('No resource url found');
49029
- return {
49030
- resourceBinary: null,
49031
- resourceEntries: [],
49032
- };
47616
+ return null;
49033
47617
  });
49034
47618
  }
49035
- prepareBootloaderSource(firmwareType) {
49036
- var _a, _b;
47619
+ prepareBootloaderBinary(firmwareType) {
49037
47620
  return __awaiter(this, void 0, void 0, function* () {
49038
- if (this.params.bootloaderBinary || ((_a = this.params.artifacts) === null || _a === void 0 ? void 0 : _a.bootloader)) {
49039
- 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;
49040
47623
  }
49041
47624
  const { features } = this.device;
49042
47625
  if (!features)
@@ -49044,32 +47627,25 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
49044
47627
  if (this.params.bootloaderVersion) {
49045
47628
  const bootResourceUrl = DataManager.getBootloaderResource(features, firmwareType);
49046
47629
  if (bootResourceUrl) {
49047
- this.assertSdkDownloadAllowed('bootloader');
49048
47630
  const bootBinary = (yield getSysResourceBinary(bootResourceUrl)).binary;
49049
- return this.openArtifactSource(bootBinary, undefined);
47631
+ return bootBinary;
49050
47632
  }
49051
47633
  }
49052
47634
  return null;
49053
47635
  });
49054
47636
  }
49055
- prepareFirmwareAndBleSources(firmwareType) {
49056
- var _a, _b, _c, _d;
47637
+ prepareFirmwareAndBleBinary(firmwareType) {
49057
47638
  return __awaiter(this, void 0, void 0, function* () {
49058
- const fwSources = [];
49059
- if (this.params.firmwareBinary || ((_a = this.params.artifacts) === null || _a === void 0 ? void 0 : _a.firmware)) {
49060
- const source = yield this.openArtifactSource(this.params.firmwareBinary, (_b = this.params.artifacts) === null || _b === void 0 ? void 0 : _b.firmware);
49061
- if (!source) {
49062
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware artifact is not prepared');
49063
- }
49064
- fwSources.push({
47639
+ const fwBinaryMap = [];
47640
+ if (this.params.firmwareBinary) {
47641
+ fwBinaryMap.push({
49065
47642
  fileName: 'firmware.bin',
49066
- source,
47643
+ binary: this.params.firmwareBinary,
49067
47644
  });
49068
47645
  }
49069
47646
  else if (this.params.firmwareVersion) {
49070
47647
  const { features } = this.device;
49071
47648
  if (features) {
49072
- this.assertSdkDownloadAllowed('firmware');
49073
47649
  const firmwareBinary = (yield getBinary({
49074
47650
  features,
49075
47651
  version: this.params.firmwareVersion,
@@ -49077,64 +47653,48 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
49077
47653
  isUpdateBootloader: false,
49078
47654
  firmwareType,
49079
47655
  })).binary;
49080
- const source = yield this.openArtifactSource(firmwareBinary, undefined);
49081
- if (!source) {
49082
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Firmware binary is not prepared');
49083
- }
49084
- fwSources.push({
47656
+ fwBinaryMap.push({
49085
47657
  fileName: 'firmware.bin',
49086
- source,
47658
+ binary: firmwareBinary,
49087
47659
  });
49088
47660
  }
49089
47661
  }
49090
- if (this.params.bleBinary || ((_c = this.params.artifacts) === null || _c === void 0 ? void 0 : _c.ble)) {
49091
- const source = yield this.openArtifactSource(this.params.bleBinary, (_d = this.params.artifacts) === null || _d === void 0 ? void 0 : _d.ble);
49092
- if (!source) {
49093
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'BLE artifact is not prepared');
49094
- }
49095
- fwSources.push({
47662
+ if (this.params.bleBinary) {
47663
+ fwBinaryMap.push({
49096
47664
  fileName: 'ble-firmware.bin',
49097
- source,
47665
+ binary: this.params.bleBinary,
49098
47666
  });
49099
47667
  }
49100
47668
  else if (this.params.bleVersion) {
49101
47669
  const { features } = this.device;
49102
47670
  if (features) {
49103
- this.assertSdkDownloadAllowed('ble');
49104
47671
  const bleBinary = yield getBinary({
49105
47672
  features,
49106
47673
  version: this.params.bleVersion,
49107
47674
  updateType: 'ble',
49108
47675
  firmwareType,
49109
47676
  });
49110
- const source = yield this.openArtifactSource(bleBinary.binary, undefined);
49111
- if (!source) {
49112
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'BLE binary is not prepared');
49113
- }
49114
- fwSources.push({
47677
+ fwBinaryMap.push({
49115
47678
  fileName: 'ble-firmware.bin',
49116
- source,
47679
+ binary: bleBinary.binary,
49117
47680
  });
49118
47681
  }
49119
47682
  }
49120
- return fwSources;
47683
+ return fwBinaryMap;
49121
47684
  });
49122
47685
  }
49123
- executeUpdate({ resourceBinary, resourceEntries, fwSources, bootloaderSource, }) {
47686
+ executeUpdate({ resourceBinary, fwBinaryMap, bootloaderBinary, }) {
49124
47687
  return __awaiter(this, void 0, void 0, function* () {
49125
47688
  let totalSize = 0;
49126
47689
  let processedSize = 0;
49127
47690
  if (resourceBinary) {
49128
47691
  totalSize += resourceBinary.byteLength;
49129
47692
  }
49130
- for (const entry of resourceEntries) {
49131
- totalSize += entry.source.size;
49132
- }
49133
- for (const firmware of fwSources) {
49134
- totalSize += firmware.source.size;
47693
+ for (const fwbinary of fwBinaryMap) {
47694
+ totalSize += fwbinary.binary.byteLength;
49135
47695
  }
49136
- if (bootloaderSource) {
49137
- totalSize += bootloaderSource.size;
47696
+ if (bootloaderBinary) {
47697
+ totalSize += bootloaderBinary.byteLength;
49138
47698
  }
49139
47699
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
49140
47700
  if (resourceBinary) {
@@ -49153,28 +47713,20 @@ class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod {
49153
47713
  }
49154
47714
  }
49155
47715
  }
49156
- for (const entry of resourceEntries) {
49157
- processedSize = yield this.emmcCommonUpdateProcessFromSource({
49158
- source: entry.source,
49159
- filePath: `0:res/${entry.entryName}`,
49160
- processedSize,
49161
- totalSize,
49162
- });
49163
- }
49164
- if (bootloaderSource) {
49165
- processedSize = yield this.emmcCommonUpdateProcessFromSource({
49166
- source: bootloaderSource,
47716
+ if (bootloaderBinary) {
47717
+ processedSize = yield this.emmcCommonUpdateProcess({
47718
+ payload: bootloaderBinary,
49167
47719
  filePath: `0:boot/bootloader.bin`,
49168
47720
  processedSize,
49169
47721
  totalSize,
49170
47722
  });
49171
47723
  }
49172
47724
  yield this.createUpdatesFolderIfNotExists(`0:updates/`);
49173
- for (const firmware of fwSources) {
49174
- if (firmware) {
49175
- processedSize = yield this.emmcCommonUpdateProcessFromSource({
49176
- source: firmware.source,
49177
- 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}`,
49178
47730
  processedSize,
49179
47731
  totalSize,
49180
47732
  });
@@ -49519,6 +48071,10 @@ const getProtocolV2DeviceTransferProgress = (bytesBeforeChunk, bytesAfterChunk,
49519
48071
  }
49520
48072
  return Math.min(Math.max(Math.ceil((bytesAfterChunk / totalBytes) * 100), 1), 99);
49521
48073
  };
48074
+ const formatProtocolV2TransferSpeed = (bytes, elapsedMs) => {
48075
+ const safeElapsedMs = Math.max(elapsedMs, 1);
48076
+ return (bytes / 1024 / (safeElapsedMs / 1000)).toFixed(2);
48077
+ };
49522
48078
  const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
49523
48079
  BOOTLOADER: {
49524
48080
  fileName: 'bootloader.bin',
@@ -49700,21 +48256,14 @@ const parseProtocolV2OkppHeader = (bytes) => {
49700
48256
  };
49701
48257
  const assertProtocolV2ReconnectIdentity = (expectedSerialNumber, actualSerialNumber) => {
49702
48258
  if (!expectedSerialNumber || !actualSerialNumber) {
49703
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, 'Protocol V2 reconnect physical identity unavailable');
48259
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, 'Protocol V2 reconnect physical identity is unavailable');
49704
48260
  }
49705
48261
  if (actualSerialNumber !== expectedSerialNumber) {
49706
48262
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Protocol V2 reconnect physical identity mismatch: expected ${expectedSerialNumber}, received ${actualSerialNumber}`);
49707
48263
  }
49708
48264
  };
49709
48265
  class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49710
- constructor() {
49711
- super(...arguments);
49712
- this.protocolV2PreparedSources = [];
49713
- this.protocolV2ExecutionInLoader = false;
49714
- this.protocolV2CompletedTargetVersions = new Map();
49715
- }
49716
48266
  init() {
49717
- var _a, _b, _c;
49718
48267
  this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
49719
48268
  this.requireDeviceMode = [];
49720
48269
  this.unlockPolicy = 'unlock-before-run';
@@ -49748,55 +48297,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49748
48297
  { name: 'firmwareType', type: 'string' },
49749
48298
  { name: 'targetsToUpdate', type: 'array', allowEmpty: true },
49750
48299
  { name: 'platform', type: 'string' },
49751
- { name: 'expectedDeviceId', type: 'string' },
49752
48300
  { name: 'resourceBundleFiles', type: 'array', allowEmpty: true },
49753
48301
  ]);
49754
- if (payload.expectedDeviceId !== undefined &&
49755
- (payload.expectedDeviceId.length === 0 || payload.expectedDeviceId.length > 160)) {
49756
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 expected device identity is invalid');
49757
- }
49758
- const hostBinding = payload.preparedPlan || payload.componentArtifacts || payload.resourceBundleArtifacts
49759
- ? resolveFirmwareUpdateHostBinding(payload.hostBindingGeneration)
49760
- : undefined;
49761
- if (hostBinding) {
49762
- if (!payload.expectedDeviceId) {
49763
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, 'Protocol V2 prepared update requires the expected device identity');
49764
- }
49765
- assertFirmwareUpdatePreparedPlanBinding({
49766
- preparedPlan: payload.preparedPlan,
49767
- executor: 'v4',
49768
- platform: payload.platform,
49769
- deviceIdentity: payload.expectedDeviceId,
49770
- scopeTargets: [
49771
- 'boot',
49772
- 'app_v1',
49773
- 'app_v2',
49774
- 'coprocessor',
49775
- 'resource',
49776
- 'se01',
49777
- 'se02',
49778
- 'se03',
49779
- 'se04',
49780
- ],
49781
- bindings: [
49782
- ...Object.entries((_a = payload.componentArtifacts) !== null && _a !== void 0 ? _a : {}).flatMap(([target, artifact]) => artifact
49783
- ? [
49784
- {
49785
- target: target,
49786
- artifact,
49787
- },
49788
- ]
49789
- : []),
49790
- ...((_b = payload.resourceBundleArtifacts) !== null && _b !== void 0 ? _b : []).map((entry) => ({
49791
- target: 'resource',
49792
- logicalName: entry.name,
49793
- artifact: entry.artifact,
49794
- })),
49795
- ],
49796
- });
49797
- }
49798
48302
  this.params = {
49799
- preparedPlan: payload.preparedPlan,
49800
48303
  chunkSize: payload.chunkSize,
49801
48304
  forcedUpdateRes: payload.forcedUpdateRes,
49802
48305
  bootloaderBinary: payload.bootloaderBinary,
@@ -49811,21 +48314,21 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49811
48314
  resourceBundleFiles: payload.resourceBundleFiles,
49812
48315
  firmwareType: payload.firmwareType,
49813
48316
  targetsToUpdate: payload.targetsToUpdate,
49814
- expectedTargetVersions: payload.expectedTargetVersions,
49815
48317
  platform: payload.platform,
49816
- expectedDeviceId: payload.expectedDeviceId,
49817
- artifactReader: (_c = hostBinding === null || hostBinding === void 0 ? void 0 : hostBinding.artifactReader) !== null && _c !== void 0 ? _c : payload.artifactReader,
49818
- componentArtifacts: payload.componentArtifacts,
49819
- resourceBundleArtifacts: payload.resourceBundleArtifacts,
49820
48318
  };
49821
48319
  }
49822
- getProtocolV2FirmwareChunkSize() {
48320
+ getProtocolV2FirmwareChunkSize(direction = 'write') {
49823
48321
  var _a, _b;
49824
48322
  const payloadChunkSize = Number((_a = this.params) === null || _a === void 0 ? void 0 : _a.chunkSize);
49825
48323
  const env = DataManager.getSettings('env');
49826
- const maxChunkSize = ((_b = this.params) === null || _b === void 0 ? void 0 : _b.platform) === 'native' || (env && DataManager.isBleConnect(env))
49827
- ? hdTransport.PROTOCOL_V2_BLE_FILE_CHUNK_SIZE
49828
- : 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
+ }
49829
48332
  if (!Number.isFinite(payloadChunkSize) || payloadChunkSize <= 0) {
49830
48333
  return maxChunkSize;
49831
48334
  }
@@ -49841,17 +48344,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49841
48344
  });
49842
48345
  }
49843
48346
  runProtocolV2() {
49844
- var _a, _b, _c;
48347
+ var _a, _b;
49845
48348
  return __awaiter(this, void 0, void 0, function* () {
49846
48349
  yield this.captureProtocolV2PhysicalIdentity();
49847
48350
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
49848
48351
  const deviceFirmwareType = getFirmwareType(deviceFeatures);
49849
48352
  const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
49850
- this.validateExpectedTargetVersions();
49851
- if ((this.params.componentArtifacts && Object.keys(this.params.componentArtifacts).length > 0) ||
49852
- ((_b = this.params.resourceBundleArtifacts) === null || _b === void 0 ? void 0 : _b.length)) {
49853
- return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
49854
- }
49855
48353
  let fwBinaryMap = [];
49856
48354
  let bootloaderBinary = null;
49857
48355
  let installItems;
@@ -49861,244 +48359,33 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
49861
48359
  fwBinaryMap = this.collectExplicitTargetBinaries();
49862
48360
  bootloaderBinary = this.prepareBootloaderBinary();
49863
48361
  if (!this.hasExplicitProtocolV2Payload(fwBinaryMap)) {
49864
- if (this.params.artifactReader ||
49865
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
49866
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware artifacts must be prepared by the external firmware host', {
49867
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49868
- });
49869
- }
49870
48362
  const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures);
49871
48363
  bootloaderBinary = remoteBinaries.bootloaderBinary;
49872
48364
  fwBinaryMap = remoteBinaries.fwBinaryMap;
49873
48365
  installItems = remoteBinaries.installItems;
49874
48366
  }
49875
- const resourceDescriptors = this.prepareProtocolV2ResourceBundles(firmwareType, deviceFeatures);
49876
- resourceBundles = (resourceDescriptors === null || resourceDescriptors === void 0 ? void 0 : resourceDescriptors.length)
49877
- ? yield this.materializeProtocolV2ResourceBundles(resourceDescriptors)
49878
- : 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
+ }
49879
48371
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
49880
48372
  }
49881
48373
  catch (err) {
49882
- 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);
49883
48375
  }
49884
48376
  if (!bootloaderBinary && fwBinaryMap.length === 0 && !(resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length)) {
49885
48377
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
49886
48378
  }
49887
- return this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
48379
+ yield this.enterProtocolV2BootloaderMode();
48380
+ yield this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
49888
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;
49889
48387
  });
49890
48388
  }
49891
- openProtocolV2PreparedSource(artifact) {
49892
- return __awaiter(this, void 0, void 0, function* () {
49893
- const source = yield openFirmwareByteSource({
49894
- artifact,
49895
- reader: this.params.artifactReader,
49896
- });
49897
- if (!source) {
49898
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Firmware artifact ${artifact.artifactRef} is not prepared`, {
49899
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49900
- });
49901
- }
49902
- this.protocolV2PreparedSources.push(source);
49903
- return source;
49904
- });
49905
- }
49906
- openProtocolV2MemorySource(binary) {
49907
- return __awaiter(this, void 0, void 0, function* () {
49908
- const source = yield openFirmwareByteSource({ binary });
49909
- if (!source) {
49910
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware binary is empty');
49911
- }
49912
- this.protocolV2PreparedSources.push(source);
49913
- return source;
49914
- });
49915
- }
49916
- closeProtocolV2PreparedSources() {
49917
- return __awaiter(this, void 0, void 0, function* () {
49918
- const sources = this.protocolV2PreparedSources.splice(0);
49919
- yield Promise.all(sources.map(source => source.close().catch(() => undefined)));
49920
- });
49921
- }
49922
- prepareProtocolV2InstallSources(firmwareType, features) {
49923
- var _a, _b;
49924
- return __awaiter(this, void 0, void 0, function* () {
49925
- const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
49926
- if (!release) {
49927
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware release is unavailable');
49928
- }
49929
- const componentArtifacts = (_a = this.params.componentArtifacts) !== null && _a !== void 0 ? _a : {};
49930
- const requestedTargets = new Set((_b = this.params.targetsToUpdate) !== null && _b !== void 0 ? _b : Object.keys(componentArtifacts));
49931
- const installSources = [];
49932
- const preparedTargets = new Set();
49933
- for (const [key, component] of this.getRemoteComponentEntries(release)) {
49934
- const target = this.getRemoteComponentTarget(key, component);
49935
- const updateTarget = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId);
49936
- if (updateTarget && updateTarget !== 'resource' && requestedTargets.has(updateTarget)) {
49937
- const artifact = componentArtifacts[updateTarget];
49938
- if (!artifact) {
49939
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 ${updateTarget} artifact is not prepared`, {
49940
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49941
- artifactName: updateTarget,
49942
- });
49943
- }
49944
- installSources.push(Object.assign(Object.assign({}, target), { source: yield this.openProtocolV2PreparedSource(artifact) }));
49945
- preparedTargets.add(updateTarget);
49946
- }
49947
- }
49948
- const unknownTarget = Array.from(requestedTargets).find(target => target !== 'resource' && !preparedTargets.has(target));
49949
- if (unknownTarget) {
49950
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain requested target ${unknownTarget}`);
49951
- }
49952
- return installSources;
49953
- });
49954
- }
49955
- prepareProtocolV2ResourceSources(firmwareType, features) {
49956
- var _a, _b, _c;
49957
- return __awaiter(this, void 0, void 0, function* () {
49958
- const preparedArtifacts = (_a = this.params.resourceBundleArtifacts) !== null && _a !== void 0 ? _a : [];
49959
- const resourceRequested = ((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource')) || preparedArtifacts.length > 0;
49960
- if (!resourceRequested) {
49961
- return [];
49962
- }
49963
- const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
49964
- const descriptors = (_c = release === null || release === void 0 ? void 0 : release.resourceBundles) !== null && _c !== void 0 ? _c : [];
49965
- const artifactByName = new Map(preparedArtifacts.map(item => [item.name, item.artifact]));
49966
- const sources = [];
49967
- for (const descriptor of descriptors) {
49968
- const artifact = artifactByName.get(descriptor.name);
49969
- if (!artifact) {
49970
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource bundle ${descriptor.name} is not prepared`, {
49971
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
49972
- artifactName: descriptor.name,
49973
- });
49974
- }
49975
- sources.push({
49976
- name: descriptor.name,
49977
- source: yield this.openProtocolV2PreparedSource(artifact),
49978
- devicePath: descriptor.devicePath,
49979
- version: descriptor.version,
49980
- payloadHash: descriptor.payloadHash,
49981
- headerHash: descriptor.headerHash,
49982
- });
49983
- artifactByName.delete(descriptor.name);
49984
- }
49985
- if (artifactByName.size > 0) {
49986
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 release does not contain resource bundle ${artifactByName.keys().next().value}`);
49987
- }
49988
- return sources;
49989
- });
49990
- }
49991
- runProtocolV2PreparedArtifacts(features, firmwareType) {
49992
- return __awaiter(this, void 0, void 0, function* () {
49993
- try {
49994
- this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
49995
- const installSources = yield this.prepareProtocolV2InstallSources(firmwareType, features);
49996
- const resourceSources = yield this.prepareProtocolV2ResourceSources(firmwareType, features);
49997
- if (installSources.length === 0 && resourceSources.length === 0) {
49998
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
49999
- }
50000
- this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
50001
- return yield this.executeProtocolV2SourceUpdate({
50002
- installSources,
50003
- resourceSources,
50004
- });
50005
- }
50006
- finally {
50007
- yield this.closeProtocolV2PreparedSources();
50008
- }
50009
- });
50010
- }
50011
- validateExpectedTargetVersions() {
50012
- const expected = this.params.expectedTargetVersions;
50013
- if (expected === undefined)
50014
- return;
50015
- if (typeof expected !== 'object' || expected === null || Array.isArray(expected)) {
50016
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 expected target versions are invalid');
50017
- }
50018
- for (const [target, version] of Object.entries(expected)) {
50019
- if (!Array.from(PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.values()).includes(target) ||
50020
- typeof version !== 'string' ||
50021
- !/^\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?$/u.test(version) ||
50022
- version.length > 64) {
50023
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 expected target version is invalid');
50024
- }
50025
- }
50026
- }
50027
- getExpectedProtocolV2TargetVersion(targetId) {
50028
- var _a, _b;
50029
- const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(targetId);
50030
- const version = target ? (_b = (_a = this.params) === null || _a === void 0 ? void 0 : _a.expectedTargetVersions) === null || _b === void 0 ? void 0 : _b[target] : undefined;
50031
- if (!version)
50032
- return undefined;
50033
- const parts = version.split(/[+-]/u, 1)[0].split('.').map(Number);
50034
- if (parts.length !== 3 ||
50035
- parts.some(part => !Number.isSafeInteger(part) || part < 0 || part > 0xff)) {
50036
- return undefined;
50037
- }
50038
- return parts[0] * 0x10000 + parts[1] * 0x100 + parts[2];
50039
- }
50040
- assertExpectedProtocolV2Versions(targets) {
50041
- var _a, _b, _c, _d, _e, _f;
50042
- const expected = (_a = this.params) === null || _a === void 0 ? void 0 : _a.expectedTargetVersions;
50043
- if (!expected)
50044
- return;
50045
- const features = this.protocolV2LatestFinalFeatures;
50046
- const requestedTargets = this.getProtocolV2RequestedTargets();
50047
- const applicationTargets = requestedTargets.filter(target => target === 'app_v1' || target === 'app_v2');
50048
- const visibleVersions = {
50049
- boot: features ? getDeviceBootloaderVersion(features).join('.') : undefined,
50050
- coprocessor: features ? getDeviceBLEFirmwareVersion(features).join('.') : undefined,
50051
- se01: (_b = features === null || features === void 0 ? void 0 : features.se01Version) !== null && _b !== void 0 ? _b : undefined,
50052
- se02: (_c = features === null || features === void 0 ? void 0 : features.se02Version) !== null && _c !== void 0 ? _c : undefined,
50053
- se03: (_d = features === null || features === void 0 ? void 0 : features.se03Version) !== null && _d !== void 0 ? _d : undefined,
50054
- se04: (_e = features === null || features === void 0 ? void 0 : features.se04Version) !== null && _e !== void 0 ? _e : undefined,
50055
- };
50056
- if (features && applicationTargets.length === 1) {
50057
- visibleVersions[applicationTargets[0]] = getDeviceFirmwareVersion(features).join('.');
50058
- }
50059
- const expectedEntries = Object.entries(expected).filter(([target]) => !targets || targets.includes(target));
50060
- for (const [target, expectedVersion] of expectedEntries) {
50061
- 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];
50062
- const statusVersion = targetId === undefined ? undefined : this.protocolV2CompletedTargetVersions.get(targetId);
50063
- const observedVersion = statusVersion === undefined
50064
- ? visibleVersions[target]
50065
- : `${Math.floor(statusVersion / 0x10000) % 0x100}.${Math.floor(statusVersion / 0x100) % 0x100}.${statusVersion % 0x100}`;
50066
- if (!observedVersion) {
50067
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 target ${target} has no observable final version`);
50068
- }
50069
- if (observedVersion !== expectedVersion) {
50070
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareVerificationFailed, `Protocol V2 target ${target} reached ${observedVersion}, expected ${expectedVersion}`);
50071
- }
50072
- }
50073
- }
50074
- getProtocolV2RequestedTargets() {
50075
- var _a, _b, _c, _d;
50076
- if ((_a = this.params.targetsToUpdate) === null || _a === void 0 ? void 0 : _a.length) {
50077
- return [...new Set(this.params.targetsToUpdate)];
50078
- }
50079
- const targets = new Set();
50080
- Object.keys((_b = this.params.componentArtifacts) !== null && _b !== void 0 ? _b : {}).forEach(target => targets.add(target));
50081
- 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)) {
50082
- targets.add('resource');
50083
- }
50084
- if (this.params.bootloaderBinary)
50085
- targets.add('boot');
50086
- if (this.params.applicationP1Binary)
50087
- targets.add('app_v1');
50088
- if (this.params.applicationP2Binary)
50089
- targets.add('app_v2');
50090
- if (this.params.coprocessorBinary)
50091
- targets.add('coprocessor');
50092
- if (this.params.se01Binary)
50093
- targets.add('se01');
50094
- if (this.params.se02Binary)
50095
- targets.add('se02');
50096
- if (this.params.se03Binary)
50097
- targets.add('se03');
50098
- if (this.params.se04Binary)
50099
- targets.add('se04');
50100
- return Array.from(targets);
50101
- }
50102
48389
  getProtocolV2DeviceFeatures() {
50103
48390
  return __awaiter(this, void 0, void 0, function* () {
50104
48391
  if (this.device.features) {
@@ -50216,7 +48503,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50216
48503
  fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE) {
50217
48504
  return null;
50218
48505
  }
50219
- const chunkSize = this.getProtocolV2FirmwareChunkSize();
48506
+ const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
50220
48507
  const chunks = [];
50221
48508
  let offset = 0;
50222
48509
  while (offset < PROTOCOL_V2_OKPP_HEADER_SIZE) {
@@ -50333,31 +48620,71 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50333
48620
  headerHash: bundle.headerHash,
50334
48621
  }));
50335
48622
  }
50336
- materializeProtocolV2ResourceBundles(bundles) {
48623
+ prefetchProtocolV2ResourceBundles(bundles) {
50337
48624
  return __awaiter(this, void 0, void 0, function* () {
48625
+ const prefetched = [];
50338
48626
  for (const bundle of bundles) {
50339
- if (bundle.binary.byteLength === 0 && bundle.url) {
50340
- if (this.params.artifactReader ||
50341
- DataManager.getSettings('firmwareManifestMode') === 'external-only') {
50342
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Firmware resource bundle ${bundle.name} is not prepared`, {
50343
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
50344
- artifactName: bundle.name,
50345
- });
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}`);
50346
48631
  }
50347
- Log$5.log(`[FirmwareUpdateV4] preloading RESC bundle ${bundle.name}`);
50348
- bundle.binary = (yield getSysResourceBinary(bundle.url)).binary;
48632
+ Log$5.log(`[FirmwareUpdateV4] downloading remote RESC bundle ${bundle.name}`);
48633
+ ({ binary } = yield getSysResourceBinary(bundle.url));
48634
+ }
48635
+ if (binary.byteLength === 0) {
48636
+ throw new Error(`Protocol V2 RESC bundle is empty: ${bundle.name}`);
50349
48637
  }
50350
- if (bundle.binary.byteLength === 0) {
50351
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, `Protocol V2 RESC bundle is empty: ${bundle.name}`);
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
+ }
50352
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
+ });
50353
48679
  }
50354
- 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 };
50355
48683
  });
50356
48684
  }
50357
48685
  isProtocolV2ResourceBundleUpToDate(bundle) {
50358
- var _a;
50359
48686
  return __awaiter(this, void 0, void 0, function* () {
50360
- if ((_a = this.params) === null || _a === void 0 ? void 0 : _a.forcedUpdateRes)
48687
+ if (this.params.forcedUpdateRes)
50361
48688
  return false;
50362
48689
  if (!bundle.version && !bundle.payloadHash)
50363
48690
  return false;
@@ -50400,7 +48727,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50400
48727
  return __awaiter(this, void 0, void 0, function* () {
50401
48728
  if (this.isProtocolV2BootloaderMode() || ((_a = this.device.features) === null || _a === void 0 ? void 0 : _a.mode) === 'romloader') {
50402
48729
  Log$5.debug('Protocol V2 device is already in loader mode, skip reboot to bootloader');
50403
- this.protocolV2ExecutionInLoader = true;
50404
48730
  return false;
50405
48731
  }
50406
48732
  try {
@@ -50409,7 +48735,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50409
48735
  this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
50410
48736
  yield hdShared.wait(1000);
50411
48737
  yield this.waitForProtocolV2BootloaderMode();
50412
- this.protocolV2ExecutionInLoader = true;
50413
48738
  return true;
50414
48739
  }
50415
48740
  catch (error) {
@@ -50469,197 +48794,73 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50469
48794
  push(this.params.se04Binary, 'se04.bin', ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04);
50470
48795
  return entries;
50471
48796
  }
50472
- buildProtocolV2ExecutionPhases({ installSources, resourceSources, }) {
50473
- const phases = [];
50474
- if (resourceSources.length > 0) {
50475
- phases.push({
50476
- kind: 'resource-sync',
50477
- installSources: [],
50478
- resourceSources,
50479
- });
50480
- }
50481
- const bootloaderSources = installSources.filter(source => source.kind === 'bootloader');
50482
- if (bootloaderSources.length > 0) {
50483
- phases.push({
50484
- kind: 'bootloader-install',
50485
- installSources: bootloaderSources,
50486
- resourceSources: [],
50487
- }, {
50488
- kind: 'bootloader-verify',
50489
- installSources: [],
50490
- resourceSources: [],
50491
- });
50492
- }
50493
- const componentSources = installSources.filter(source => source.kind !== 'bootloader');
50494
- if (componentSources.length > 0) {
50495
- phases.push({
50496
- kind: 'component-install',
50497
- installSources: componentSources,
50498
- resourceSources: [],
50499
- });
50500
- }
50501
- phases.push({
50502
- kind: 'final-verify',
50503
- installSources: [],
50504
- resourceSources: [],
50505
- });
50506
- return phases;
50507
- }
50508
- executeProtocolV2Phases({ installSources, resourceSources, }) {
50509
- return __awaiter(this, void 0, void 0, function* () {
50510
- const phases = this.buildProtocolV2ExecutionPhases({
50511
- installSources,
50512
- resourceSources,
50513
- });
50514
- for (const phase of phases) {
50515
- if (phase.kind === 'final-verify') {
50516
- return this.completeProtocolV2FinalVerification();
50517
- }
50518
- if (phase.kind === 'resource-sync') {
50519
- yield this.enterProtocolV2BootloaderMode();
50520
- yield this.executeProtocolV2TransferPhase(phase);
50521
- }
50522
- else if (phase.kind === 'bootloader-install' || phase.kind === 'component-install') {
50523
- yield this.enterProtocolV2BootloaderMode();
50524
- yield this.executeProtocolV2TransferPhase(phase);
50525
- yield this.exitProtocolV2BootloaderToNormal();
50526
- }
50527
- else if (phase.kind === 'bootloader-verify') {
50528
- yield this.waitForProtocolV2FinalFeatures();
50529
- this.assertExpectedProtocolV2Versions(['boot']);
50530
- }
50531
- }
50532
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 execution has no final verification phase');
50533
- });
50534
- }
50535
- executeProtocolV2SourceUpdate({ installSources, resourceSources, }) {
50536
- return __awaiter(this, void 0, void 0, function* () {
50537
- return this.executeProtocolV2Phases({
50538
- installSources,
50539
- resourceSources,
50540
- });
50541
- });
50542
- }
50543
48797
  executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles, }) {
50544
48798
  return __awaiter(this, void 0, void 0, function* () {
50545
- const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
50546
- fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
48799
+ const orderedInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
50547
48800
  bootloaderBinary: bootloaderBinary !== null && bootloaderBinary !== void 0 ? bootloaderBinary : null,
48801
+ fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
50548
48802
  });
50549
- try {
50550
- const installSources = yield Promise.all(memoryInstallItems.map((item) => __awaiter(this, void 0, void 0, function* () {
50551
- return ({
50552
- fileName: item.fileName,
50553
- source: yield this.openProtocolV2MemorySource(item.binary),
50554
- targetId: item.targetId,
50555
- kind: item.kind,
50556
- });
50557
- })));
50558
- const resourceSources = yield Promise.all((resourceBundles !== null && resourceBundles !== void 0 ? resourceBundles : []).map((bundle) => __awaiter(this, void 0, void 0, function* () {
50559
- return ({
50560
- name: bundle.name,
50561
- source: yield this.openProtocolV2MemorySource(bundle.binary),
50562
- devicePath: bundle.devicePath,
50563
- version: bundle.version,
50564
- payloadHash: bundle.payloadHash,
50565
- headerHash: bundle.headerHash,
50566
- });
50567
- })));
50568
- return yield this.executeProtocolV2Phases({
50569
- installSources,
50570
- resourceSources,
50571
- });
50572
- }
50573
- finally {
50574
- yield this.closeProtocolV2PreparedSources();
50575
- }
50576
- });
50577
- }
50578
- executeProtocolV2TransferPhase({ installSources, resourceSources, }) {
50579
- return __awaiter(this, void 0, void 0, function* () {
50580
- let totalSize = installSources.reduce((total, item) => total + item.source.size, 0);
50581
- const resourcesToSync = [];
50582
- for (const resource of resourceSources) {
50583
- if (yield this.isProtocolV2ResourceBundleUpToDate(resource)) {
50584
- Log$5.log(`[FirmwareUpdateV4] skip RESC bundle ${resource.name}; already up to date`);
50585
- }
50586
- else {
50587
- resourcesToSync.push(resource);
50588
- totalSize += resource.source.size;
50589
- }
50590
- }
48803
+ let firmwareSize = 0;
48804
+ for (const item of orderedInstallItems)
48805
+ firmwareSize += item.binary.byteLength;
50591
48806
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
50592
48807
  let processedSize = 0;
50593
- for (const resource of resourcesToSync) {
50594
- processedSize = yield this.protocolV2SourceUpdateProcess({
50595
- source: resource.source,
50596
- filePath: resource.devicePath,
50597
- processedSize,
50598
- totalSize,
50599
- });
50600
- 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;
50601
48813
  }
50602
- const stagedInstallTargets = [];
50603
- for (const item of installSources) {
50604
- const filePath = this.getProtocolV2InstallItemStagingPath(item);
50605
- processedSize = yield this.protocolV2SourceUpdateProcess({
50606
- source: item.source,
50607
- filePath,
50608
- processedSize,
50609
- totalSize,
50610
- });
50611
- yield this.verifyProtocolV2StagedFile(filePath, item.source.size);
50612
- stagedInstallTargets.push({
50613
- targetId: item.targetId,
50614
- path: filePath,
50615
- });
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;
50616
48820
  }
50617
- if (totalSize > 0) {
50618
- 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`);
50619
48850
  }
50620
- if (stagedInstallTargets.length === 0) {
50621
- 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;
50622
48855
  }
50623
48856
  this.postTipMessage(exports.FirmwareUpdateTipMessage.ConfirmOnDevice);
50624
- const targets = stagedInstallTargets.map(item => ({
48857
+ const allTargets = stagedInstallTargets.map(item => ({
50625
48858
  target_id: item.targetId,
50626
48859
  path: item.path,
50627
48860
  }));
50628
- yield this.protocolV2StartFirmwareUpdate({ targets });
50629
- yield this.waitForProtocolV2FirmwareUpdateComplete(targets);
50630
- });
50631
- }
50632
- protocolV2SourceUpdateProcess({ source, filePath, processedSize, totalSize, }) {
50633
- return __awaiter(this, void 0, void 0, function* () {
50634
- let lastError;
50635
- for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
50636
- try {
50637
- yield writeFirmwareByteSource({
50638
- source,
50639
- chunkSize: this.getProtocolV2FirmwareChunkSize(),
50640
- write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
50641
- const chunkEnd = sourceOffset + length;
50642
- const progress = getProtocolV2DeviceTransferProgress(processedSize + sourceOffset, processedSize + chunkEnd, totalSize);
50643
- const response = yield this.fileWriteChunk(filePath, source.size, sourceOffset, data, first, progress);
50644
- const rawProcessedByte = response.message.processed_byte;
50645
- const nextOffset = rawProcessedByte === undefined ? chunkEnd : Number(rawProcessedByte);
50646
- if (!Number.isFinite(nextOffset) || nextOffset !== chunkEnd) {
50647
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `invalid processed_byte ${rawProcessedByte} for offset ${sourceOffset}`);
50648
- }
50649
- this.postProgressMessage(progress, 'transferData');
50650
- return length;
50651
- }),
50652
- });
50653
- return processedSize + source.size;
50654
- }
50655
- catch (error) {
50656
- lastError = error;
50657
- if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
50658
- yield this.recoverProtocolV2FileTransfer();
50659
- }
50660
- }
50661
- }
50662
- 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);
50663
48864
  });
50664
48865
  }
50665
48866
  getProtocolV2InstallItemStagingPath(item) {
@@ -50676,7 +48877,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50676
48877
  }
50677
48878
  });
50678
48879
  }
50679
- assertProtocolV2TargetStatus(statusTargets, expectedTargetIds, expectedPaths = new Map()) {
48880
+ assertProtocolV2TargetStatus(statusTargets, expectedTargetIds) {
50680
48881
  var _a, _b, _c;
50681
48882
  Log$5.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateStatus records=${JSON.stringify(statusTargets)}`);
50682
48883
  const failedTarget = statusTargets.find(target => {
@@ -50695,34 +48896,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50695
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'}`);
50696
48897
  }
50697
48898
  const matchingTargets = statusTargets.filter(target => { var _a; return expectedTargetIds.has((_a = normalizeProtocolV2TargetId(target.target_id)) !== null && _a !== void 0 ? _a : -1); });
50698
- const seenTargetIds = new Set();
50699
- for (const target of matchingTargets) {
50700
- const targetId = normalizeProtocolV2TargetId(target.target_id);
50701
- if (targetId === undefined ||
50702
- seenTargetIds.has(targetId) ||
50703
- (target.path && expectedPaths.get(targetId) && target.path !== expectedPaths.get(targetId))) {
50704
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 install status conflicts with target ${target.target_id}`);
50705
- }
50706
- seenTargetIds.add(targetId);
50707
- }
50708
48899
  const completedTargets = matchingTargets.filter(target => isProtocolV2TargetStatusFinished(target.status));
50709
48900
  if (completedTargets.length === expectedTargetIds.size && expectedTargetIds.size > 0) {
50710
- for (const target of completedTargets) {
50711
- const targetId = normalizeProtocolV2TargetId(target.target_id);
50712
- const payloadVersion = toProtocolV2FiniteNumber(target.payload_version);
50713
- if (targetId === undefined) {
50714
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 completed target identity is invalid');
50715
- }
50716
- const expectedVersion = this.getExpectedProtocolV2TargetVersion(targetId);
50717
- if (expectedVersion !== undefined && payloadVersion !== undefined) {
50718
- if (payloadVersion !== expectedVersion) {
50719
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareVerificationFailed, `Protocol V2 target ${targetId} reached payload version ${payloadVersion}, expected ${expectedVersion}`);
50720
- }
50721
- }
50722
- if (payloadVersion !== undefined) {
50723
- this.protocolV2CompletedTargetVersions.set(targetId, payloadVersion);
50724
- }
50725
- }
50726
48901
  this.postProgressMessage(100, 'installingFirmware');
50727
48902
  return true;
50728
48903
  }
@@ -50735,10 +48910,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50735
48910
  return false;
50736
48911
  }
50737
48912
  waitForProtocolV2FirmwareUpdateComplete(targets) {
50738
- var _a, _b;
48913
+ var _a;
50739
48914
  return __awaiter(this, void 0, void 0, function* () {
50740
48915
  const expectedTargetIds = new Set(targets.map(target => target.target_id));
50741
- const expectedPaths = new Map(targets.map(target => [target.target_id, target.path]));
50742
48916
  const startTime = Date.now();
50743
48917
  let lastError;
50744
48918
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
@@ -50753,7 +48927,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50753
48927
  path: true,
50754
48928
  },
50755
48929
  }, { timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT });
50756
- 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)) {
50757
48931
  return;
50758
48932
  }
50759
48933
  lastError = new Error('Protocol V2 firmware targets are still installing');
@@ -50764,24 +48938,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50764
48938
  throw error;
50765
48939
  }
50766
48940
  if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
50767
- try {
50768
- const deviceInfo = yield requestProtocolV2DeviceInfo({
50769
- commands: this.device.getCommands(),
50770
- timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
50771
- });
50772
- this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
50773
- const observed = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
50774
- if (observed.mode === 'normal' && !observed.bootloaderMode) {
50775
- return;
50776
- }
50777
- lastError = new Error('Protocol V2 status endpoint is unavailable outside normal mode');
50778
- }
50779
- catch (probeError) {
50780
- lastError = probeError;
50781
- }
50782
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 firmware install status is unavailable: ${this.normalizeErrorMessage(lastError)}`, {
50783
- firmwareUpdateCode: 'FirmwareInstallStatusUnavailable',
50784
- });
48941
+ Log$5.log('[FirmwareUpdateV4] firmware status endpoint unavailable after reboot; continue with normal-mode verification');
48942
+ return;
50785
48943
  }
50786
48944
  lastError = error;
50787
48945
  Log$5.log('[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ', error);
@@ -50795,10 +48953,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50795
48953
  if (error instanceof hdShared.HardwareError && error.errorCode === hdShared.HardwareErrorCode.FirmwareError) {
50796
48954
  throw error;
50797
48955
  }
50798
- if (error instanceof hdShared.HardwareError &&
50799
- ((_b = error.params) === null || _b === void 0 ? void 0 : _b.firmwareUpdateCode) === 'FirmwareInstallStatusUnavailable') {
50800
- throw error;
50801
- }
50802
48956
  Log$5.log('Protocol V2 firmware install device readiness probe failed: ', error);
50803
48957
  }
50804
48958
  yield hdShared.wait(1000);
@@ -50811,7 +48965,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50811
48965
  yield this.reconnectProtocolV2Device();
50812
48966
  yield this.verifyProtocolV2ReconnectIdentity();
50813
48967
  yield this.protocolV2Reboot(hdTransport.DeviceRebootType.Normal);
50814
- this.protocolV2ExecutionInLoader = false;
50815
48968
  });
50816
48969
  }
50817
48970
  waitForProtocolV2FinalFeatures() {
@@ -50820,7 +48973,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50820
48973
  const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
50821
48974
  const bleVersion = getDeviceBLEFirmwareVersion(features).join('.');
50822
48975
  const firmwareVersion = getDeviceFirmwareVersion(features).join('.');
50823
- this.protocolV2LatestFinalFeatures = features;
50824
48976
  if (firmwareVersion === '0.0.0') {
50825
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.');
50826
48978
  }
@@ -50831,18 +48983,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50831
48983
  };
50832
48984
  });
50833
48985
  }
50834
- completeProtocolV2FinalVerification() {
50835
- return __awaiter(this, void 0, void 0, function* () {
50836
- if (this.protocolV2ExecutionInLoader || this.isProtocolV2BootloaderMode()) {
50837
- yield this.exitProtocolV2BootloaderToNormal();
50838
- }
50839
- const versions = yield this.waitForProtocolV2FinalFeatures();
50840
- this.assertExpectedProtocolV2Versions();
50841
- this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdateCompleted);
50842
- DevicePool.resetState();
50843
- return versions;
50844
- });
50845
- }
50846
48986
  waitForProtocolV2ReconnectAndFeatures(timeout) {
50847
48987
  return __awaiter(this, void 0, void 0, function* () {
50848
48988
  const startTime = Date.now();
@@ -50918,6 +49058,66 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
50918
49058
  isProtocolV2ReconnectIdentityError(error) {
50919
49059
  return this.normalizeErrorMessage(error).includes('Protocol V2 reconnect physical identity');
50920
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
+ }
50921
49121
  fileWriteChunk(filePath, totalFileSize, offset, chunk, overwrite, progress) {
50922
49122
  var _a;
50923
49123
  return __awaiter(this, void 0, void 0, function* () {
@@ -60797,6 +58997,7 @@ class NeoSignTransaction extends BaseMethod {
60797
58997
  var ApiMethods = /*#__PURE__*/Object.freeze({
60798
58998
  __proto__: null,
60799
58999
  testInitializeDeviceDuration: TestInitializeDeviceDuration,
59000
+ testProtocolV2Ping: Ping,
60800
59001
  preInitialize: PreInitialize,
60801
59002
  searchDevices: SearchDevices,
60802
59003
  getFeatures: GetFeatures,
@@ -61342,7 +59543,7 @@ class ProtocolV2UiInteractionCoordinator {
61342
59543
 
61343
59544
  const Log$1 = getLogger(exports.LoggerNames.Core);
61344
59545
  function runMethodWithUnlockRetry(method, device, uiCoordinator) {
61345
- var _a;
59546
+ var _a, _b, _c, _d;
61346
59547
  return __awaiter(this, void 0, void 0, function* () {
61347
59548
  const shouldEmitUi = isProtocolV2UiEnabled(method);
61348
59549
  const shouldUnlockBeforeRun = device.isProtocolV2() && method.unlockPolicy !== 'none' && ((_a = device.features) === null || _a === void 0 ? void 0 : _a.unlocked) === false;
@@ -61375,6 +59576,15 @@ function runMethodWithUnlockRetry(method, device, uiCoordinator) {
61375
59576
  }
61376
59577
  yield device.unlockDevice();
61377
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
+ }
61378
59588
  if (shouldEmitUi) {
61379
59589
  uiCoordinator === null || uiCoordinator === void 0 ? void 0 : uiCoordinator.resumeMethodInteraction();
61380
59590
  }
@@ -61472,7 +59682,6 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
61472
59682
  }
61473
59683
  return createResponseMessage((_b = method === null || method === void 0 ? void 0 : method.responseID) !== null && _b !== void 0 ? _b : message.id, false, { error });
61474
59684
  }
61475
- DevicePool.emitter.on(DEVICE.CONNECT, onDeviceConnectHandler);
61476
59685
  if (!method.useDevice) {
61477
59686
  updateMethodRequestContext(method, { status: 'running' });
61478
59687
  try {
@@ -61506,7 +59715,6 @@ const callAPI = (context, message) => __awaiter(void 0, void 0, void 0, function
61506
59715
  });
61507
59716
  const handlePreWarmSignal = (context, message, method) => __awaiter(void 0, void 0, void 0, function* () {
61508
59717
  const createAckResponse = () => {
61509
- DevicePool.emitter.removeListener(DEVICE.CONNECT, onDeviceConnectHandler);
61510
59718
  completeMethodRequestContext(method);
61511
59719
  method.dispose();
61512
59720
  return createResponseMessage(method.responseID, true, true);
@@ -61933,8 +60141,14 @@ function connectDeviceForBle(method, device, retryCount = 0) {
61933
60141
  var _a;
61934
60142
  return __awaiter(this, void 0, void 0, function* () {
61935
60143
  try {
61936
- 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
+ }
61937
60148
  if ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.onlyConnectBleDevice) {
60149
+ if (shouldAcquire) {
60150
+ DevicePool.emitter.emit(DEVICE.CONNECT, device);
60151
+ }
61938
60152
  return;
61939
60153
  }
61940
60154
  if (!canSkipInitialize(method, device)) {
@@ -61944,6 +60158,9 @@ function connectDeviceForBle(method, device, retryCount = 0) {
61944
60158
  passphraseState: initOptions.passphraseState,
61945
60159
  });
61946
60160
  }
60161
+ if (shouldAcquire) {
60162
+ DevicePool.emitter.emit(DEVICE.CONNECT, device);
60163
+ }
61947
60164
  }
61948
60165
  catch (err) {
61949
60166
  if ((err.errorCode === hdShared.HardwareErrorCode.BleTimeoutError ||
@@ -62181,7 +60398,6 @@ const cleanup = () => {
62181
60398
  };
62182
60399
  const removeDeviceListener = (device) => {
62183
60400
  device.removeAllListeners();
62184
- DevicePool.emitter.removeAllListeners(DEVICE.CONNECT);
62185
60401
  };
62186
60402
  const closePopup = () => {
62187
60403
  postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_WINDOW));
@@ -62199,6 +60415,16 @@ const onDeviceDisconnectHandler = (device) => {
62199
60415
  return;
62200
60416
  postMessage(createDeviceMessage(DEVICE.DISCONNECT, { device: deviceObject }));
62201
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
+ };
62202
60428
  const onDevicePinHandler = (...[device, type, callback]) => __awaiter(void 0, void 0, void 0, function* () {
62203
60429
  Log.log('request Input PIN');
62204
60430
  const uiPromise = createUiPromise(UI_RESPONSE.RECEIVE_PIN, device);
@@ -62236,6 +60462,7 @@ const onDevicePassphraseHandler = (...[device, requestPayload, callback]) => __a
62236
60462
  device: device.toMessageObject(),
62237
60463
  passphraseState: device.passphraseState,
62238
60464
  existsAttachPinUser: requestPayload.existsAttachPinUser,
60465
+ deviceOnly: requestPayload.deviceOnly,
62239
60466
  source: requestPayload.source,
62240
60467
  reason: requestPayload.reason,
62241
60468
  expectedPassphraseState: requestPayload.expectedPassphraseState,
@@ -62425,7 +60652,12 @@ const initCore = () => {
62425
60652
  };
62426
60653
  const initConnector = () => {
62427
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);
62428
60659
  DevicePool.emitter.on(DEVICE.DISCONNECT, onDeviceDisconnectHandler);
60660
+ DevicePool.emitter.on(hdTransport.TRANSPORT_EVENT.DEVICE_DISCONNECT, onTransportDeviceDisconnectHandler);
62429
60661
  return _connector;
62430
60662
  };
62431
60663
  const initTransport = (Transport, plugin) => {
@@ -62567,7 +60799,6 @@ exports.getEnv = getEnv;
62567
60799
  exports.getFirmwareType = getFirmwareType;
62568
60800
  exports.getFirmwareUpdateField = getFirmwareUpdateField;
62569
60801
  exports.getFirmwareUpdateFieldArray = getFirmwareUpdateFieldArray;
62570
- exports.getFirmwareUpdateHostBindingGeneration = getFirmwareUpdateHostBindingGeneration;
62571
60802
  exports.getHDPath = getHDPath;
62572
60803
  exports.getHomeScreenDefaultList = getHomeScreenDefaultList;
62573
60804
  exports.getHomeScreenHex = getHomeScreenHex;
@@ -62593,12 +60824,10 @@ exports.parseConnectSettings = parseConnectSettings;
62593
60824
  exports.parseMessage = parseMessage;
62594
60825
  exports.patchFeatures = patchFeatures;
62595
60826
  exports.preloadSessionCache = preloadSessionCache;
62596
- exports.registerFirmwareUpdateHostBinding = registerFirmwareUpdateHostBinding;
62597
60827
  exports.safeThrowError = safeThrowError;
62598
60828
  exports.setLoggerPostMessage = setLoggerPostMessage;
62599
60829
  exports.supportInputPinOnSoftware = supportInputPinOnSoftware;
62600
60830
  exports.switchTransport = switchTransport;
62601
- exports.unregisterFirmwareUpdateHostBinding = unregisterFirmwareUpdateHostBinding;
62602
60831
  exports.updateRequestContext = updateRequestContext;
62603
60832
  exports.versionCompare = versionCompare;
62604
60833
  exports.versionSplit = versionSplit;