@onekeyfe/hd-core 1.2.0-alpha.147 → 1.2.0-alpha.149

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 (39) hide show
  1. package/__tests__/device-lifecycle-events.test.ts +177 -2
  2. package/__tests__/device-utils.test.ts +8 -0
  3. package/__tests__/deviceUploadNft.test.ts +3 -0
  4. package/__tests__/protocol-v2-resources.test.ts +35 -89
  5. package/__tests__/protocol-v2-unlock-policy.test.ts +72 -0
  6. package/__tests__/protocol-v2.test.ts +51 -188
  7. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  8. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  9. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  10. package/dist/api/protocol-v2/DeviceReboot.d.ts +1 -1
  11. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
  12. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
  13. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  14. package/dist/core/index.d.ts +2 -0
  15. package/dist/core/index.d.ts.map +1 -1
  16. package/dist/device/Device.d.ts +6 -0
  17. package/dist/device/Device.d.ts.map +1 -1
  18. package/dist/index.d.ts +17 -20
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +212 -314
  21. package/dist/protocols/protocol-v2/resources.d.ts +11 -7
  22. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  23. package/dist/types/settings.d.ts +0 -13
  24. package/dist/types/settings.d.ts.map +1 -1
  25. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  26. package/package.json +4 -4
  27. package/src/api/FirmwareUpdateV4.ts +61 -238
  28. package/src/api/PromptWebDeviceAccess.ts +2 -2
  29. package/src/api/device/DeviceRebootToBoardloader.ts +3 -1
  30. package/src/api/device/DeviceRebootToBootloader.ts +3 -1
  31. package/src/api/protocol-v2/DeviceReboot.ts +5 -0
  32. package/src/api/protocol-v2/DeviceUploadNft.ts +5 -1
  33. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +5 -1
  34. package/src/core/index.ts +31 -106
  35. package/src/device/Device.ts +71 -8
  36. package/src/index.ts +0 -4
  37. package/src/protocols/protocol-v2/resources.ts +92 -102
  38. package/src/types/settings.ts +0 -15
  39. package/src/utils/deviceInfoUtils.ts +7 -2
package/dist/index.js CHANGED
@@ -466,10 +466,13 @@ const getDeviceTypeByBleName = (name) => {
466
466
  return hdShared.EDeviceType.Touch;
467
467
  if (/^Touch/i.test(name))
468
468
  return hdShared.EDeviceType.Touch;
469
- if (/\bPro\s*2\b/i.test(name) || /^Pro2/i.test(name))
469
+ const compactName = name.replace(/[\s-]/g, '');
470
+ if (/\bPro\s*2\b/i.test(name) || /^Pro2/i.test(name) || /^(?:OneKey)?Pro2/i.test(compactName)) {
470
471
  return hdShared.EDeviceType.Pro2;
471
- if (/\bNeo\b/i.test(name) || /^Neo/i.test(name))
472
+ }
473
+ if (/\bNeo\b/i.test(name) || /^Neo/i.test(name) || /^(?:OneKey)?Neo/i.test(compactName)) {
472
474
  return hdShared.EDeviceType.Neo;
475
+ }
473
476
  if (/\bPro\b/i.test(name) || /^Pro/i.test(name))
474
477
  return hdShared.EDeviceType.Pro;
475
478
  return hdShared.EDeviceType.Unknown;
@@ -40675,18 +40678,16 @@ const findLatestRelease = (releases) => {
40675
40678
  return leastRelease;
40676
40679
  };
40677
40680
 
40678
- const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH$1 = 'vol0:/loaders/bootloader/boot_resource.okpkg';
40679
- const SHA256_HEX_LENGTH = 64;
40680
- function normalizeHex$1(value, expectedLength, field) {
40681
- if (typeof value !== 'string') {
40682
- throw new Error(`Invalid Pro2 resource ${field}: expected a hexadecimal string`);
40683
- }
40684
- const normalized = value.replace(/^0x/i, '').toLowerCase();
40685
- if (normalized.length !== expectedLength || !/^[0-9a-f]+$/.test(normalized)) {
40686
- throw new Error(`Invalid Pro2 resource ${field}: expected ${expectedLength} hexadecimal characters`);
40687
- }
40688
- return normalized;
40689
- }
40681
+ const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH = 'vol0:/loaders/bootloader/boot_resource.okpkg';
40682
+ const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH = `${PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH}.staging`;
40683
+ const PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE = 0x5f90;
40684
+ const PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_VERSION = 1;
40685
+ const PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_OFFSET = 0x6c;
40686
+ const PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_SIZE = 64;
40687
+ const PROTOCOL_V2_RESOURCE_PACKAGE_PAYLOAD_HASH_OFFSET = 0x200;
40688
+ const PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_HASH_OFFSET = 0x240;
40689
+ const PROTOCOL_V2_RESOURCE_PACKAGE_HASH_SIZE = 64;
40690
+ const PROTOCOL_V2_RESOURCE_PACKAGE_TYPE = 'RESC';
40690
40691
  function parseProtocolV2Resources(value) {
40691
40692
  if (value === undefined)
40692
40693
  return undefined;
@@ -40715,86 +40716,75 @@ function parseProtocolV2Resources(value) {
40715
40716
  },
40716
40717
  };
40717
40718
  }
40718
- const PROTOCOL_V2_RESOURCE_MANIFEST_DEVICE_ROOTS = [
40719
- 'vol0:/bundles/',
40720
- 'vol0:/loaders/rom/',
40721
- ];
40722
- function isAllowedManifestDevicePath(path) {
40723
- if (!path.endsWith('.okpkg') ||
40724
- path.includes('\\') ||
40719
+ const PROTOCOL_V2_RESOURCE_DEVICE_ROOTS = ['vol0:/bundles/', 'vol0:/loaders/rom/'];
40720
+ function isAllowedResourceDevicePath(path) {
40721
+ if (path.includes('\\') ||
40725
40722
  path.includes('//') ||
40723
+ [...path].some(char => {
40724
+ const code = char.charCodeAt(0);
40725
+ return code <= 0x1f || code === 0x7f;
40726
+ }) ||
40726
40727
  path.split('/').some(part => part === '.' || part === '..')) {
40727
40728
  return false;
40728
40729
  }
40729
- if (path === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH$1) {
40730
+ if (path === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH) {
40730
40731
  return true;
40731
40732
  }
40732
- return PROTOCOL_V2_RESOURCE_MANIFEST_DEVICE_ROOTS.some(root => path.startsWith(root));
40733
+ return (path.endsWith('.okpkg') && PROTOCOL_V2_RESOURCE_DEVICE_ROOTS.some(root => path.startsWith(root)));
40733
40734
  }
40734
- function assertManifestString(value, field) {
40735
- if (typeof value !== 'string' || value.length === 0) {
40736
- throw new Error(`Invalid Pro2 resource manifest ${field}`);
40737
- }
40738
- return value;
40735
+ function readAscii(bytes, offset, length) {
40736
+ return Array.from(bytes.slice(offset, offset + length))
40737
+ .map(byte => String.fromCharCode(byte))
40738
+ .join('');
40739
40739
  }
40740
- function assertManifestRelativePath(value, field) {
40741
- const path = assertManifestString(value, field);
40742
- if (path.startsWith('/') ||
40743
- path.includes('\\') ||
40744
- path.includes(':') ||
40745
- path.split('/').some(part => !part || part === '.' || part === '..')) {
40746
- throw new Error(`Invalid Pro2 resource manifest ${field}`);
40740
+ function readResourceDevicePath(bytes) {
40741
+ const metadata = bytes.slice(PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_OFFSET, PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_OFFSET + PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_SIZE);
40742
+ const terminator = metadata.indexOf(0);
40743
+ const pathBytes = terminator === -1 ? metadata : metadata.slice(0, terminator);
40744
+ const padding = terminator === -1 ? new Uint8Array(0) : metadata.slice(terminator);
40745
+ if (pathBytes.byteLength === 0 ||
40746
+ Array.from(pathBytes).some(byte => byte < 0x20 || byte > 0x7e) ||
40747
+ Array.from(padding).some(byte => byte !== 0)) {
40748
+ throw new Error('Invalid Pro2 RESOURCE package device path metadata');
40749
+ }
40750
+ const path = readAscii(pathBytes, 0, pathBytes.byteLength);
40751
+ if (!isAllowedResourceDevicePath(path)) {
40752
+ throw new Error(`Invalid Pro2 RESOURCE package device path: ${path}`);
40747
40753
  }
40748
40754
  return path;
40749
40755
  }
40750
- function parseProtocolV2ResourceManifestFile(value, index) {
40751
- var _a;
40752
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
40753
- throw new Error(`Invalid Pro2 resource manifest files[${index}]`);
40754
- }
40755
- const file = value;
40756
- const archivePath = assertManifestRelativePath(file.archive_path, `files[${index}].archive_path`);
40757
- const originalName = file.original_name === undefined
40758
- ? (_a = archivePath.split('/').pop()) !== null && _a !== void 0 ? _a : archivePath
40759
- : assertManifestRelativePath(file.original_name, `files[${index}].original_name`);
40760
- if (originalName.includes('/')) {
40761
- throw new Error(`Invalid Pro2 resource manifest files[${index}].original_name`);
40762
- }
40763
- const devicePath = assertManifestString(file.device_path, `files[${index}].device_path`);
40764
- if (!isAllowedManifestDevicePath(devicePath)) {
40765
- throw new Error(`Invalid Pro2 resource manifest files[${index}].device_path`);
40766
- }
40767
- if (!Number.isSafeInteger(file.size) || Number(file.size) <= 0) {
40768
- throw new Error(`Invalid Pro2 resource manifest files[${index}].size`);
40769
- }
40770
- const digest = normalizeHex$1(file.sha256, SHA256_HEX_LENGTH, `files[${index}].sha256`);
40771
- if (!archivePath.endsWith('.okpkg') || !originalName.endsWith('.okpkg')) {
40772
- throw new Error(`Invalid Pro2 resource manifest files[${index}] package extension`);
40756
+ function parseProtocolV2ResourcePackageHeader(bytes, packageSize) {
40757
+ if (bytes.byteLength < PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE) {
40758
+ throw new Error('Pro2 RESOURCE package is shorter than its header');
40773
40759
  }
40774
- return Object.assign(Object.assign(Object.assign({ archive_path: archivePath, original_name: originalName, device_path: devicePath, size: Number(file.size), sha256: digest }, (file.signed === undefined ? {} : { signed: file.signed })), (file.sig_algo === undefined ? {} : { sig_algo: file.sig_algo })), (file.payload_version === undefined ? {} : { payload_version: file.payload_version }));
40775
- }
40776
- function parseProtocolV2ResourceManifest(value) {
40777
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
40778
- throw new Error('Invalid Pro2 resource manifest');
40779
- }
40780
- const manifest = value;
40781
- if (!Array.isArray(manifest.files)) {
40782
- throw new Error('Invalid Pro2 resource manifest files');
40783
- }
40784
- const files = manifest.files.map(parseProtocolV2ResourceManifestFile);
40785
- const devicePaths = new Set(files.map(file => file.device_path));
40786
- const archivePaths = new Set(files.map(file => file.archive_path));
40787
- if (files.length === 0 ||
40788
- devicePaths.size !== files.length ||
40789
- archivePaths.size !== files.length) {
40790
- throw new Error('Invalid Pro2 resource manifest file set');
40760
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
40761
+ const headerVersion = view.getUint32(0x04, true);
40762
+ const headerLength = view.getUint32(0x0c, true);
40763
+ const payloadLength = view.getUint32(0x14, true);
40764
+ if (readAscii(bytes, 0, 4) !== 'OKPP' ||
40765
+ readAscii(bytes, 0x08, 4) !== PROTOCOL_V2_RESOURCE_PACKAGE_TYPE ||
40766
+ headerVersion !== PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_VERSION ||
40767
+ headerLength !== PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE ||
40768
+ payloadLength <= 0 ||
40769
+ headerLength + payloadLength !== packageSize) {
40770
+ throw new Error('Invalid Pro2 RESOURCE package header');
40791
40771
  }
40772
+ const packedVersion = view.getUint32(0x10, true);
40792
40773
  return {
40793
- files,
40774
+ version: [
40775
+ Math.floor(packedVersion / 0x10000) % 0x100,
40776
+ Math.floor(packedVersion / 0x100) % 0x100,
40777
+ packedVersion % 0x100,
40778
+ ],
40779
+ payloadLength,
40780
+ devicePath: readResourceDevicePath(bytes),
40781
+ payloadHash: utils.bytesToHex(bytes.slice(PROTOCOL_V2_RESOURCE_PACKAGE_PAYLOAD_HASH_OFFSET, PROTOCOL_V2_RESOURCE_PACKAGE_PAYLOAD_HASH_OFFSET + PROTOCOL_V2_RESOURCE_PACKAGE_HASH_SIZE)),
40782
+ headerHash: utils.bytesToHex(bytes.slice(PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_HASH_OFFSET, PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_HASH_OFFSET + PROTOCOL_V2_RESOURCE_PACKAGE_HASH_SIZE)),
40794
40783
  };
40795
40784
  }
40796
- function selectProtocolV2ResourceManifestFiles({ manifest, targetsToUpdate, }) {
40797
- return targetsToUpdate.includes('resource') ? [...manifest.files] : [];
40785
+ function parseProtocolV2ResourcePackage(binary) {
40786
+ const bytes = binary instanceof Uint8Array ? binary : new Uint8Array(binary);
40787
+ return parseProtocolV2ResourcePackageHeader(bytes, bytes.byteLength);
40798
40788
  }
40799
40789
 
40800
40790
  var _a$1;
@@ -45140,6 +45130,8 @@ class Device extends events.exports {
45140
45130
  super();
45141
45131
  this.deviceConnector = null;
45142
45132
  this.deviceAcquired = false;
45133
+ this.connectionAttempt = 0;
45134
+ this.interruptedAttempt = null;
45143
45135
  this.stateStore = new DeviceStateStore();
45144
45136
  this.protocolV2StateNeedsReload = false;
45145
45137
  this.protocolV2UiInteractionCounter = 0;
@@ -45232,8 +45224,10 @@ class Device extends events.exports {
45232
45224
  }));
45233
45225
  }
45234
45226
  acquire(expectedProtocol, options) {
45235
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
45227
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
45236
45228
  return __awaiter(this, void 0, void 0, function* () {
45229
+ const attempt = this.connectionAttempt;
45230
+ this.throwIfInterruptedByUser();
45237
45231
  const env = DataManager.getSettings('env');
45238
45232
  const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
45239
45233
  const previousProtocol = this.originalDescriptor.protocolType;
@@ -45259,12 +45253,21 @@ class Device extends events.exports {
45259
45253
  if (detectedProtocol) {
45260
45254
  this.originalDescriptor.protocolType = detectedProtocol;
45261
45255
  }
45256
+ if (this.interruptedAttempt === attempt || this.connectionAttempt !== attempt) {
45257
+ const session = this.mainId;
45258
+ if (session && ((_g = this.deviceConnector) === null || _g === void 0 ? void 0 : _g.disconnect)) {
45259
+ yield this.deviceConnector.disconnect(session).catch(disconnectError => {
45260
+ Log$h.debug('Ignored disconnect after user cancel during acquire', disconnectError);
45261
+ });
45262
+ }
45263
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
45264
+ }
45262
45265
  this.deviceAcquired = true;
45263
45266
  this.updateDescriptor({ [mainIdKey]: this.mainId });
45264
45267
  if (this.commands) {
45265
45268
  yield this.commands.dispose(false);
45266
45269
  }
45267
- this.commands = new DeviceCommands(this, (_g = this.mainId) !== null && _g !== void 0 ? _g : '');
45270
+ this.commands = new DeviceCommands(this, (_h = this.mainId) !== null && _h !== void 0 ? _h : '');
45268
45271
  this.invalidateProtocolV2RuntimeState();
45269
45272
  }
45270
45273
  catch (error) {
@@ -45274,7 +45277,7 @@ class Device extends events.exports {
45274
45277
  this.deviceAcquired = false;
45275
45278
  if (failedSession) {
45276
45279
  try {
45277
- yield ((_j = (_h = this.deviceConnector) === null || _h === void 0 ? void 0 : _h.release) === null || _j === void 0 ? void 0 : _j.call(_h, failedSession, false));
45280
+ yield ((_k = (_j = this.deviceConnector) === null || _j === void 0 ? void 0 : _j.release) === null || _k === void 0 ? void 0 : _k.call(_j, failedSession, false));
45278
45281
  }
45279
45282
  catch (releaseError) {
45280
45283
  Log$h.debug('Failed to release an unsuccessful protocol probe', releaseError);
@@ -45596,6 +45599,7 @@ class Device extends events.exports {
45596
45599
  }
45597
45600
  initialize(options) {
45598
45601
  return __awaiter(this, void 0, void 0, function* () {
45602
+ this.throwIfInterruptedByUser();
45599
45603
  if (this.isProtocolV2()) {
45600
45604
  this.passphraseState = options === null || options === void 0 ? void 0 : options.passphraseState;
45601
45605
  if (this.state && !(options === null || options === void 0 ? void 0 : options.initSession) && !this.protocolV2StateNeedsReload) {
@@ -46017,6 +46021,7 @@ class Device extends events.exports {
46017
46021
  yield this.interruptionFromOutside();
46018
46022
  Log$h.debug('[Device] run error:', 'Device is running, but will cancel previous operate');
46019
46023
  }
46024
+ this.beginConnectionAttempt();
46020
46025
  options = parseRunOptions(options);
46021
46026
  const runPromise = hdShared.createDeferred();
46022
46027
  this.runPromise = runPromise;
@@ -46127,25 +46132,29 @@ class Device extends events.exports {
46127
46132
  });
46128
46133
  }
46129
46134
  interruptionFromUser() {
46130
- var _a, _b, _c;
46135
+ var _a, _b, _c, _d;
46131
46136
  return __awaiter(this, void 0, void 0, function* () {
46132
46137
  const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46138
+ this.interruptedAttempt = this.connectionAttempt;
46133
46139
  const cleanupPromise = this.runCleanupPromise;
46134
46140
  const { cancelableAction } = this;
46135
- const env = DataManager.getSettings('env');
46136
46141
  if (cancelableAction) {
46137
46142
  yield cancelableAction(error);
46138
46143
  }
46139
- else if (this.isProtocolV2() &&
46140
- (DataManager.isBleConnect(env) ||
46141
- DataManager.isBrowserWebUsb(env) ||
46142
- DataManager.isDesktopWebUsb(env)) &&
46143
- this.hasDeviceAcquire()) {
46144
+ else if (this.shouldSendFallbackProtocolCancel()) {
46144
46145
  yield ((_b = (_a = this.commands) === null || _a === void 0 ? void 0 : _a.cancelDevice) === null || _b === void 0 ? void 0 : _b.call(_a).catch(cancelError => {
46145
46146
  Log$h.debug('Protocol V2 fallback cancel error', cancelError);
46146
46147
  }));
46147
46148
  }
46148
- yield ((_c = this.commands) === null || _c === void 0 ? void 0 : _c.cancel());
46149
+ else if (!this.hasDeviceAcquire()) {
46150
+ if (this.mainId && ((_c = this.deviceConnector) === null || _c === void 0 ? void 0 : _c.disconnect)) {
46151
+ yield this.deviceConnector.disconnect(this.mainId).catch(disconnectError => {
46152
+ Log$h.debug('Ignored disconnect during user cancel without acquire', disconnectError);
46153
+ });
46154
+ }
46155
+ this.markTransportDisconnected();
46156
+ }
46157
+ yield ((_d = this.commands) === null || _d === void 0 ? void 0 : _d.cancel());
46149
46158
  if (this.runPromise) {
46150
46159
  this.runPromise.reject(error);
46151
46160
  this.runPromise = null;
@@ -46200,6 +46209,31 @@ class Device extends events.exports {
46200
46209
  isUsed() {
46201
46210
  return typeof this.originalDescriptor.session === 'string';
46202
46211
  }
46212
+ beginConnectionAttempt() {
46213
+ this.connectionAttempt += 1;
46214
+ return this.connectionAttempt;
46215
+ }
46216
+ wasInterruptedByUser() {
46217
+ return (typeof this.interruptedAttempt === 'number' &&
46218
+ this.interruptedAttempt === this.connectionAttempt);
46219
+ }
46220
+ throwIfInterruptedByUser() {
46221
+ if (this.wasInterruptedByUser()) {
46222
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46223
+ }
46224
+ }
46225
+ shouldSendFallbackProtocolCancel() {
46226
+ if (!this.hasDeviceAcquire() || !this.isProtocolV2()) {
46227
+ return false;
46228
+ }
46229
+ if (!this.hasOpenProtocolV2UiInteraction()) {
46230
+ return false;
46231
+ }
46232
+ const env = DataManager.getSettings('env');
46233
+ return (DataManager.isBleConnect(env) ||
46234
+ DataManager.isBrowserWebUsb(env) ||
46235
+ DataManager.isDesktopWebUsb(env));
46236
+ }
46203
46237
  hasDeviceAcquire() {
46204
46238
  const env = DataManager.getSettings('env');
46205
46239
  if (DataManager.isBleConnect(env)) {
@@ -48253,6 +48287,8 @@ class DeviceRebootToBootloader extends BaseMethod {
48253
48287
  init() {
48254
48288
  this.useDevicePassphraseState = false;
48255
48289
  this.skipForceUpdateCheck = true;
48290
+ this.unlockPolicy = 'unlock-before-run';
48291
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
48256
48292
  }
48257
48293
  getVersionRange() {
48258
48294
  return {
@@ -48286,6 +48322,8 @@ class DeviceRebootToBoardloader extends BaseMethod {
48286
48322
  init() {
48287
48323
  this.useDevicePassphraseState = false;
48288
48324
  this.skipForceUpdateCheck = true;
48325
+ this.unlockPolicy = 'unlock-before-run';
48326
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
48289
48327
  }
48290
48328
  getVersionRange() {
48291
48329
  return {
@@ -51771,17 +51809,8 @@ const PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS = 1000;
51771
51809
  const PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE = 'FirmwareInstallStatusConflict';
51772
51810
  const PROTOCOL_V2_INSTALL_FAILED_CODE = 'FirmwareInstallFailed';
51773
51811
  const PROTOCOL_V2_INSTALL_TIMEOUT_CODE = 'FirmwareInstallTimeout';
51774
- const PROTOCOL_V2_OKPP_HEADER_SIZE = 0x52a0;
51775
- const PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET = 0x200;
51776
- const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET = 0x240;
51777
- const PROTOCOL_V2_OKPP_HASH_SIZE = 64;
51778
- const PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES = 1024 * 1024;
51779
51812
  const PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT = 512;
51780
51813
  const PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES = 256 * 1024 * 1024;
51781
- const getProtocolV2LocalResourceArchivePath = (entryName) => {
51782
- const match = entryName.match(/(?:^|\/)((?:bundles\/|loaders\/(?:bootloader|rom)\/).+\.okpkg)$/iu);
51783
- return match === null || match === void 0 ? void 0 : match[1];
51784
- };
51785
51814
  const PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS = new Set(['se03', 'se04']);
51786
51815
  const getProtocolV2ZipEntrySizes = (entry) => {
51787
51816
  var _a;
@@ -51875,14 +51904,8 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
51875
51904
  },
51876
51905
  };
51877
51906
  const PROTOCOL_V2_FIRMWARE_STAGING_PATHS = new Set(Object.values(PROTOCOL_V2_REMOTE_COMPONENT_TARGETS).map(target => `${PROTOCOL_V2_FIRMWARE_STAGING_VOLUME}${target.fileName}`));
51878
- const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH = 'vol0:/loaders/bootloader/boot_resource.okpkg';
51879
- const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH = `${PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH}.staging`;
51880
51907
  const isProtocolV2BootResourcePackagePath = (devicePath) => typeof devicePath === 'string' &&
51881
- devicePath.replace(/^vol0:(?!\/)/i, 'vol0:/').toLowerCase() ===
51882
- PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH;
51883
- const resolveProtocolV2ResourceWritePath = (devicePath) => isProtocolV2BootResourcePackagePath(devicePath)
51884
- ? PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH
51885
- : devicePath;
51908
+ devicePath.toLowerCase() === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH;
51886
51909
  const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
51887
51910
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, 'boot'],
51888
51911
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, 'app_v1'],
@@ -52008,30 +52031,6 @@ const toProtocolV2FiniteNumber = (value) => {
52008
52031
  }
52009
52032
  return undefined;
52010
52033
  };
52011
- const readProtocolV2Ascii = (bytes, offset, length) => Array.from(bytes.slice(offset, offset + length))
52012
- .map(byte => String.fromCharCode(byte))
52013
- .join('');
52014
- const parseProtocolV2OkppHeader = (bytes) => {
52015
- if (bytes.byteLength < PROTOCOL_V2_OKPP_HEADER_SIZE)
52016
- return null;
52017
- if (readProtocolV2Ascii(bytes, 0, 4) !== 'OKPP')
52018
- return null;
52019
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
52020
- const headerLen = view.getUint32(0x0c, true);
52021
- if (headerLen !== PROTOCOL_V2_OKPP_HEADER_SIZE)
52022
- return null;
52023
- const packedVersion = view.getUint32(0x10, true);
52024
- return {
52025
- type: readProtocolV2Ascii(bytes, 0x08, 4),
52026
- version: [
52027
- Math.floor(packedVersion / 0x10000) % 0x100,
52028
- Math.floor(packedVersion / 0x100) % 0x100,
52029
- packedVersion % 0x100,
52030
- ],
52031
- payloadHash: bytesToHex(bytes.slice(PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET, PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET + PROTOCOL_V2_OKPP_HASH_SIZE)),
52032
- headerHash: bytesToHex(bytes.slice(PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET, PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET + PROTOCOL_V2_OKPP_HASH_SIZE)),
52033
- };
52034
- };
52035
52034
  const isProtocolV2FirmwareFingerprintValid = (binary, fingerprint) => {
52036
52035
  const expectedFingerprint = normalizeProtocolV2Hex(fingerprint);
52037
52036
  if (!expectedFingerprint)
@@ -52539,7 +52538,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52539
52538
  });
52540
52539
  }
52541
52540
  prepareProtocolV2LocalResourceArchive(binary) {
52542
- var _a;
52543
52541
  return __awaiter(this, void 0, void 0, function* () {
52544
52542
  if (binary.byteLength <= 0 || binary.byteLength > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52545
52543
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP archive size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
@@ -52548,91 +52546,47 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52548
52546
  try {
52549
52547
  zip = yield JSZip__default["default"].loadAsync(binary);
52550
52548
  }
52551
- catch (_b) {
52549
+ catch (_a) {
52552
52550
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource ZIP cannot be parsed', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52553
52551
  }
52554
52552
  const zipEntries = Object.values(zip.files);
52555
- if (zipEntries.some(entry => entry.unsafeOriginalName && entry.unsafeOriginalName !== entry.name)) {
52556
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unsafe entry path', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52557
- }
52558
- const entries = zipEntries.filter(entry => !entry.dir);
52559
- if (entries.length === 0) {
52560
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP entry set is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52561
- }
52562
- const manifestEntry = entries.find(entry => entry.name.split('/').pop() === 'manifest.json');
52563
- let manifestBinary;
52564
- let manifestDirectory = '';
52565
- let selectedFiles;
52566
- if (manifestEntry) {
52567
- if (getProtocolV2ZipEntrySizes(manifestEntry).uncompressedSize >
52568
- PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52569
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52570
- }
52571
- manifestBinary = yield manifestEntry.async('arraybuffer');
52572
- if (manifestBinary.byteLength <= 0 ||
52573
- manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52574
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52575
- }
52576
- let manifestValue;
52577
- try {
52578
- manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
52579
- }
52580
- catch (error) {
52581
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52582
- }
52583
- selectedFiles = selectProtocolV2ResourceManifestFiles({
52584
- manifest: parseProtocolV2ResourceManifest(manifestValue),
52585
- targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
52586
- });
52587
- manifestDirectory = manifestEntry.name.slice(0, -'manifest.json'.length);
52588
- }
52589
- else {
52590
- selectedFiles = entries.flatMap(entry => {
52591
- var _a;
52592
- const archivePath = getProtocolV2LocalResourceArchivePath(entry.name);
52593
- if (!archivePath)
52594
- return [];
52595
- return [
52596
- {
52597
- archive_path: archivePath,
52598
- original_name: (_a = archivePath.split('/').pop()) !== null && _a !== void 0 ? _a : archivePath,
52599
- device_path: `vol0:/${archivePath}`,
52600
- size: getProtocolV2ZipEntrySizes(entry).uncompressedSize,
52601
- sha256: '',
52602
- },
52603
- ];
52604
- });
52605
- }
52606
- if (selectedFiles.length === 0 || selectedFiles.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
52607
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no resource packages', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52553
+ const resourceEntries = zipEntries.filter(entry => !entry.dir && entry.name.toLowerCase().endsWith('.okpkg'));
52554
+ if (resourceEntries.length === 0 ||
52555
+ resourceEntries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
52556
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource ZIP has no valid resource package set', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52608
52557
  }
52609
52558
  let totalSize = 0;
52610
52559
  const materializedEntries = [];
52611
- const normalizedFiles = [];
52612
- for (const file of selectedFiles) {
52613
- const entry = manifestEntry
52614
- ? zip.file(`${manifestDirectory}${file.archive_path}`)
52615
- : entries.find(candidate => getProtocolV2LocalResourceArchivePath(candidate.name) === file.archive_path);
52616
- if (!entry) {
52617
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP is missing ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52618
- }
52619
- const { uncompressedSize } = getProtocolV2ZipEntrySizes(entry);
52560
+ const resources = [];
52561
+ const devicePaths = new Set();
52562
+ for (const entry of resourceEntries) {
52563
+ const { compressedSize, uncompressedSize } = getProtocolV2ZipEntrySizes(entry);
52620
52564
  totalSize += uncompressedSize;
52621
- if (uncompressedSize !== file.size || totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52622
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file declared size is invalid: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52565
+ if (compressedSize > binary.byteLength ||
52566
+ uncompressedSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES ||
52567
+ totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52568
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource package size is invalid: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52623
52569
  }
52624
52570
  const fileBinary = yield entry.async('arraybuffer');
52625
- const digest = bytesToHex(sha256.sha256(new Uint8Array(fileBinary)));
52626
- if (fileBinary.byteLength !== file.size ||
52627
- (file.sha256 && digest !== file.sha256.toLowerCase())) {
52628
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52571
+ if (fileBinary.byteLength !== uncompressedSize) {
52572
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource package is incomplete: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52573
+ }
52574
+ let header;
52575
+ try {
52576
+ header = parseProtocolV2ResourcePackage(fileBinary);
52577
+ }
52578
+ catch (error) {
52579
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource package is invalid: ${entry.name}: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52629
52580
  }
52630
- normalizedFiles.push(Object.assign(Object.assign({}, file), { sha256: digest }));
52631
- materializedEntries.push({ entryName: file.archive_path, binary: fileBinary });
52581
+ const canonicalDevicePath = header.devicePath.toLowerCase();
52582
+ if (devicePaths.has(canonicalDevicePath)) {
52583
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource ZIP contains duplicate device path: ${header.devicePath}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52584
+ }
52585
+ devicePaths.add(canonicalDevicePath);
52586
+ materializedEntries.push({ entryName: entry.name, binary: fileBinary });
52587
+ resources.push({ entryName: entry.name, binary: fileBinary, header });
52632
52588
  }
52633
- manifestBinary !== null && manifestBinary !== void 0 ? manifestBinary : (manifestBinary = new TextEncoder().encode(JSON.stringify({ files: normalizedFiles })).buffer);
52634
- materializedEntries.unshift({ entryName: 'manifest.json', binary: manifestBinary });
52635
- return { binary, materializedEntries };
52589
+ return { binary, materializedEntries, resources };
52636
52590
  });
52637
52591
  }
52638
52592
  prepareProtocolV2ResourceSources() {
@@ -52678,48 +52632,17 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52678
52632
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive does not match its approved receipt', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52679
52633
  }
52680
52634
  const verifiedArchive = yield this.prepareProtocolV2LocalResourceArchive(archiveBinary);
52681
- const verifiedEntriesByName = new Map(verifiedArchive.materializedEntries.map(entry => [entry.entryName, entry.binary]));
52682
- const manifestBinary = verifiedEntriesByName.get('manifest.json');
52683
- if (!manifestBinary) {
52684
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive has no valid manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52685
- }
52686
- let manifestValue;
52687
- try {
52688
- manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
52689
- }
52690
- catch (error) {
52691
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52692
- }
52693
- const manifest = parseProtocolV2ResourceManifest(manifestValue);
52694
- const selectedFiles = selectProtocolV2ResourceManifestFiles({
52695
- manifest,
52696
- targetsToUpdate: (_c = this.params.targetsToUpdate) !== null && _c !== void 0 ? _c : [],
52697
- });
52698
- if (selectedFiles.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
52699
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive contains too many files', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52700
- }
52701
- let totalSize = 0;
52702
52635
  const sources = [];
52703
- for (const [index, file] of selectedFiles.entries()) {
52704
- const binary = verifiedEntriesByName.get(file.archive_path);
52705
- if (!binary || binary.byteLength !== file.size) {
52706
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 prepared resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52707
- }
52708
- totalSize += binary.byteLength;
52709
- if (totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52710
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive exceeds the total size limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52711
- }
52712
- const source = yield this.openProtocolV2MemorySource(binary);
52713
- const header = source.size >= PROTOCOL_V2_OKPP_HEADER_SIZE
52714
- ? parseProtocolV2OkppHeader(new Uint8Array(yield source.readAt(0, PROTOCOL_V2_OKPP_HEADER_SIZE)))
52715
- : null;
52716
- sources.push(Object.assign({ name: file.original_name || `resource-${index}`, source, devicePath: file.device_path }, (header
52717
- ? {
52718
- version: header.version,
52719
- payloadHash: header.payloadHash,
52720
- headerHash: header.headerHash,
52721
- }
52722
- : {})));
52636
+ for (const resource of verifiedArchive.resources) {
52637
+ const source = yield this.openProtocolV2MemorySource(resource.binary);
52638
+ sources.push({
52639
+ name: (_c = resource.entryName.split('/').pop()) !== null && _c !== void 0 ? _c : resource.entryName,
52640
+ source,
52641
+ devicePath: resource.header.devicePath,
52642
+ version: resource.header.version,
52643
+ payloadHash: resource.header.payloadHash,
52644
+ headerHash: resource.header.headerHash,
52645
+ });
52723
52646
  }
52724
52647
  return sources;
52725
52648
  });
@@ -53101,15 +53024,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53101
53024
  if (!((_b = pathInfoRes.message) === null || _b === void 0 ? void 0 : _b.exist) ||
53102
53025
  ((_c = pathInfoRes.message) === null || _c === void 0 ? void 0 : _c.directory) ||
53103
53026
  fileSize === undefined ||
53104
- fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE ||
53027
+ fileSize < PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE ||
53105
53028
  (expectedSize !== undefined && fileSize !== expectedSize)) {
53106
53029
  return null;
53107
53030
  }
53108
53031
  const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
53109
53032
  const chunks = [];
53110
53033
  let offset = 0;
53111
- while (offset < PROTOCOL_V2_OKPP_HEADER_SIZE) {
53112
- const readLen = Math.min(chunkSize, PROTOCOL_V2_OKPP_HEADER_SIZE - offset);
53034
+ while (offset < PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE) {
53035
+ const readLen = Math.min(chunkSize, PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE - offset);
53113
53036
  const res = yield typedCall('FilesystemFileRead', 'FilesystemFile', {
53114
53037
  file: {
53115
53038
  path: filePath,
@@ -53131,7 +53054,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53131
53054
  headerBytes.set(chunk, cursor);
53132
53055
  cursor += chunk.byteLength;
53133
53056
  });
53134
- return parseProtocolV2OkppHeader(headerBytes);
53057
+ try {
53058
+ return parseProtocolV2ResourcePackageHeader(headerBytes, fileSize);
53059
+ }
53060
+ catch (_e) {
53061
+ return null;
53062
+ }
53135
53063
  });
53136
53064
  }
53137
53065
  isProtocolV2ResourceBundleUpToDate(bundle) {
@@ -53357,7 +53285,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53357
53285
  this.protocolV2LastTransferProgressAt = 0;
53358
53286
  let processedSize = 0;
53359
53287
  for (const resource of resourcesToSync) {
53360
- const writePath = resolveProtocolV2ResourceWritePath(resource.devicePath);
53288
+ const writePath = resource.devicePath;
53361
53289
  processedSize = yield this.protocolV2SourceUpdateProcess({
53362
53290
  source: resource.source,
53363
53291
  filePath: writePath,
@@ -54008,7 +53936,7 @@ class PromptWebDeviceAccess extends BaseMethod {
54008
53936
  }
54009
53937
  if (isWebUsbEnv) {
54010
53938
  const usbDevice = device;
54011
- const path = usbDevice.serialNumber;
53939
+ const path = hdShared.resolveOneKeyUsbDevicePath(usbDevice);
54012
53940
  if (!path) {
54013
53941
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WebDevicePromptAccessError);
54014
53942
  }
@@ -54042,6 +53970,8 @@ class DeviceReboot extends BaseMethod {
54042
53970
  init() {
54043
53971
  this.skipForceUpdateCheck = true;
54044
53972
  this.useDevicePassphraseState = false;
53973
+ this.unlockPolicy = 'unlock-before-run';
53974
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
54045
53975
  this.params = {
54046
53976
  rebootType: this.payload.rebootType,
54047
53977
  reboot_type: this.payload.reboot_type,
@@ -54446,7 +54376,8 @@ class DeviceUploadWallpaper extends BaseMethod {
54446
54376
  });
54447
54377
  this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
54448
54378
  this.params = { jpegBase64, fileName, chunkSize };
54449
- this.unlockPolicy = 'none';
54379
+ this.unlockPolicy = 'unlock-before-run';
54380
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
54450
54381
  this.skipForceUpdateCheck = true;
54451
54382
  this.useDevicePassphraseState = false;
54452
54383
  }
@@ -54602,7 +54533,8 @@ class DeviceUploadNft extends BaseMethod {
54602
54533
  paceMs,
54603
54534
  timeoutMs,
54604
54535
  };
54605
- this.unlockPolicy = 'none';
54536
+ this.unlockPolicy = 'unlock-before-run';
54537
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
54606
54538
  this.skipForceUpdateCheck = true;
54607
54539
  this.useDevicePassphraseState = false;
54608
54540
  }
@@ -65282,7 +65214,6 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65282
65214
  if ((_g = method.payload) === null || _g === void 0 ? void 0 : _g.onlyConnectBleDevice) {
65283
65215
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
65284
65216
  Log.debug('Call API - only connect ble device: ', device === null || device === void 0 ? void 0 : device.mainId);
65285
- requestQueue.releaseTask(method.responseID);
65286
65217
  return createResponseMessage(method.responseID, true, null);
65287
65218
  }
65288
65219
  Log.debug('Call API - setDevice: ', device.mainId);
@@ -65632,12 +65563,25 @@ function canSkipInitialize(method, device) {
65632
65563
  return true;
65633
65564
  }
65634
65565
  function isRetryableBleProtocolV2ProbeError(method, error) {
65635
- const message = error instanceof Error ? error.message : String(error !== null && error !== void 0 ? error : '');
65566
+ const typedError = error;
65567
+ const message = typeof (typedError === null || typedError === void 0 ? void 0 : typedError.message) === 'string' ? typedError.message : String(error !== null && error !== void 0 ? error : '');
65636
65568
  return (method.payload.connectProtocol === 'V2' &&
65569
+ (typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.RuntimeError &&
65637
65570
  message.includes('Device protocol mismatch') &&
65638
65571
  message.includes('expected V2') &&
65639
65572
  message.includes('did not respond to expected protocol'));
65640
65573
  }
65574
+ function isRetryableBleConnectionError(method, error) {
65575
+ var _a;
65576
+ if ((_a = method.device) === null || _a === void 0 ? void 0 : _a.wasInterruptedByUser()) {
65577
+ return false;
65578
+ }
65579
+ const typedError = error;
65580
+ return ((typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError ||
65581
+ (typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleConnectedError ||
65582
+ isRetryableBleProtocolV2ProbeError(method, error) ||
65583
+ isMissingDetectedProtocolV2Error(method, error));
65584
+ }
65641
65585
  function isMissingDetectedProtocolV2Error(method, error) {
65642
65586
  const typedError = error;
65643
65587
  return (method.payload.connectProtocol === 'V2' &&
@@ -65645,34 +65589,16 @@ function isMissingDetectedProtocolV2Error(method, error) {
65645
65589
  typeof typedError.message === 'string' &&
65646
65590
  typedError.message.includes('Device protocol has not been detected'));
65647
65591
  }
65648
- const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
65649
- function raceBleAcquire(acquirePromise, abortSignal) {
65650
- return new Promise((resolve, reject) => {
65651
- let settled = false;
65652
- const settle = (fn) => {
65653
- if (settled)
65654
- return;
65655
- settled = true;
65656
- clearTimeout(deadline);
65657
- abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', onAbort);
65658
- fn();
65659
- };
65660
- const onAbort = () => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled)));
65661
- const deadline = setTimeout(() => settle(() => reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`))), BLE_ACQUIRE_DEADLINE_MS);
65662
- acquirePromise.then(value => settle(() => resolve(value)), error => settle(() => reject(error)));
65663
- if (abortSignal) {
65664
- if (abortSignal.aborted) {
65665
- onAbort();
65666
- return;
65667
- }
65668
- abortSignal.addEventListener('abort', onAbort);
65669
- }
65670
- });
65671
- }
65672
- function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
65592
+ function connectDeviceForBle(method, device, retryCount = 0) {
65673
65593
  var _a;
65674
65594
  return __awaiter(this, void 0, void 0, function* () {
65675
65595
  try {
65596
+ if (retryCount === 0) {
65597
+ device.beginConnectionAttempt();
65598
+ }
65599
+ if (device.wasInterruptedByUser()) {
65600
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
65601
+ }
65676
65602
  if (method.payload.forceProtocolDetection && device.hasDeviceAcquire()) {
65677
65603
  yield device.release();
65678
65604
  }
@@ -65681,31 +65607,9 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
65681
65607
  !device.commands ||
65682
65608
  device.commands.disposed;
65683
65609
  if (shouldAcquire) {
65684
- const useAcquireGuards = DataManager.getSettings('env') === 'desktop-web-ble';
65685
- if (useAcquireGuards && (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted)) {
65686
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
65687
- }
65688
- if (!useAcquireGuards) {
65689
- yield device.acquire(method.payload.connectProtocol, {
65690
- forceProtocolDetection: method.payload.forceProtocolDetection,
65691
- });
65692
- }
65693
- else {
65694
- try {
65695
- yield raceBleAcquire(device.acquire(method.payload.connectProtocol, {
65696
- forceProtocolDetection: method.payload.forceProtocolDetection,
65697
- }), abortSignal);
65698
- }
65699
- catch (err) {
65700
- if (err.errorCode === hdShared.HardwareErrorCode.BleTimeoutError &&
65701
- device.mainId &&
65702
- device.deviceConnector) {
65703
- yield device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
65704
- device.markTransportDisconnected();
65705
- }
65706
- throw err;
65707
- }
65708
- }
65610
+ yield device.acquire(method.payload.connectProtocol, {
65611
+ forceProtocolDetection: method.payload.forceProtocolDetection,
65612
+ });
65709
65613
  }
65710
65614
  if ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.onlyConnectBleDevice) {
65711
65615
  if (shouldAcquire) {
@@ -65732,15 +65636,11 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
65732
65636
  yield device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
65733
65637
  device.markTransportDisconnected();
65734
65638
  }
65735
- if ((err.errorCode === hdShared.HardwareErrorCode.BleTimeoutError ||
65736
- err.errorCode === hdShared.HardwareErrorCode.BleConnectedError ||
65737
- isRetryableBleProtocolV2ProbeError(method, err) ||
65738
- requiresColdReconnect) &&
65739
- retryCount < 6) {
65639
+ if (isRetryableBleConnectionError(method, err) && retryCount < 6) {
65740
65640
  const nextRetry = retryCount + 1;
65741
65641
  Log.debug(`Bluetooth connection will retry, retry count: ${nextRetry}`);
65742
65642
  yield wait(3000);
65743
- yield connectDeviceForBle(method, device, abortSignal, nextRetry);
65643
+ yield connectDeviceForBle(method, device, nextRetry);
65744
65644
  }
65745
65645
  else {
65746
65646
  throw err;
@@ -65822,7 +65722,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
65822
65722
  if (abort()) {
65823
65723
  return;
65824
65724
  }
65825
- yield connectDeviceForBle(method, device, abortSignal);
65725
+ yield connectDeviceForBle(method, device);
65826
65726
  }
65827
65727
  resolve(device);
65828
65728
  return;
@@ -66418,14 +66318,12 @@ exports.normalizeSafetyCheckLevel = normalizeSafetyCheckLevel;
66418
66318
  exports.normalizeVersionArray = normalizeVersionArray;
66419
66319
  exports.parseConnectSettings = parseConnectSettings;
66420
66320
  exports.parseMessage = parseMessage;
66421
- exports.parseProtocolV2ResourceManifest = parseProtocolV2ResourceManifest;
66422
66321
  exports.patchFeatures = patchFeatures;
66423
66322
  exports.preloadSessionCache = preloadSessionCache;
66424
66323
  exports.prepareFirmwareUpdateV4MemoryHost = prepareFirmwareUpdateV4MemoryHost;
66425
66324
  exports.projectDeviceStateFeatures = projectFeatures;
66426
66325
  exports.registerFirmwareUpdateHostBinding = registerFirmwareUpdateHostBinding;
66427
66326
  exports.safeThrowError = safeThrowError;
66428
- exports.selectProtocolV2ResourceManifestFiles = selectProtocolV2ResourceManifestFiles;
66429
66327
  exports.setLoggerPostMessage = setLoggerPostMessage;
66430
66328
  exports.supportInputPinOnSoftware = supportInputPinOnSoftware;
66431
66329
  exports.switchTransport = switchTransport;