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

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 +128 -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 +4 -0
  17. package/dist/device/Device.d.ts.map +1 -1
  18. package/dist/index.d.ts +14 -20
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +202 -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 +28 -106
  35. package/src/device/Device.ts +59 -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`);
40773
- }
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');
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');
40783
40759
  }
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,7 @@ class Device extends events.exports {
45140
45130
  super();
45141
45131
  this.deviceConnector = null;
45142
45132
  this.deviceAcquired = false;
45133
+ this.interruptedByUser = false;
45143
45134
  this.stateStore = new DeviceStateStore();
45144
45135
  this.protocolV2StateNeedsReload = false;
45145
45136
  this.protocolV2UiInteractionCounter = 0;
@@ -45232,8 +45223,9 @@ class Device extends events.exports {
45232
45223
  }));
45233
45224
  }
45234
45225
  acquire(expectedProtocol, options) {
45235
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
45226
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
45236
45227
  return __awaiter(this, void 0, void 0, function* () {
45228
+ this.throwIfInterruptedByUser();
45237
45229
  const env = DataManager.getSettings('env');
45238
45230
  const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
45239
45231
  const previousProtocol = this.originalDescriptor.protocolType;
@@ -45259,12 +45251,21 @@ class Device extends events.exports {
45259
45251
  if (detectedProtocol) {
45260
45252
  this.originalDescriptor.protocolType = detectedProtocol;
45261
45253
  }
45254
+ if (this.interruptedByUser) {
45255
+ const session = this.mainId;
45256
+ if (session && ((_g = this.deviceConnector) === null || _g === void 0 ? void 0 : _g.disconnect)) {
45257
+ yield this.deviceConnector.disconnect(session).catch(disconnectError => {
45258
+ Log$h.debug('Ignored disconnect after user cancel during acquire', disconnectError);
45259
+ });
45260
+ }
45261
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
45262
+ }
45262
45263
  this.deviceAcquired = true;
45263
45264
  this.updateDescriptor({ [mainIdKey]: this.mainId });
45264
45265
  if (this.commands) {
45265
45266
  yield this.commands.dispose(false);
45266
45267
  }
45267
- this.commands = new DeviceCommands(this, (_g = this.mainId) !== null && _g !== void 0 ? _g : '');
45268
+ this.commands = new DeviceCommands(this, (_h = this.mainId) !== null && _h !== void 0 ? _h : '');
45268
45269
  this.invalidateProtocolV2RuntimeState();
45269
45270
  }
45270
45271
  catch (error) {
@@ -45274,7 +45275,7 @@ class Device extends events.exports {
45274
45275
  this.deviceAcquired = false;
45275
45276
  if (failedSession) {
45276
45277
  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));
45278
+ 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
45279
  }
45279
45280
  catch (releaseError) {
45280
45281
  Log$h.debug('Failed to release an unsuccessful protocol probe', releaseError);
@@ -45596,6 +45597,7 @@ class Device extends events.exports {
45596
45597
  }
45597
45598
  initialize(options) {
45598
45599
  return __awaiter(this, void 0, void 0, function* () {
45600
+ this.throwIfInterruptedByUser();
45599
45601
  if (this.isProtocolV2()) {
45600
45602
  this.passphraseState = options === null || options === void 0 ? void 0 : options.passphraseState;
45601
45603
  if (this.state && !(options === null || options === void 0 ? void 0 : options.initSession) && !this.protocolV2StateNeedsReload) {
@@ -46017,6 +46019,7 @@ class Device extends events.exports {
46017
46019
  yield this.interruptionFromOutside();
46018
46020
  Log$h.debug('[Device] run error:', 'Device is running, but will cancel previous operate');
46019
46021
  }
46022
+ this.interruptedByUser = false;
46020
46023
  options = parseRunOptions(options);
46021
46024
  const runPromise = hdShared.createDeferred();
46022
46025
  this.runPromise = runPromise;
@@ -46127,25 +46130,29 @@ class Device extends events.exports {
46127
46130
  });
46128
46131
  }
46129
46132
  interruptionFromUser() {
46130
- var _a, _b, _c;
46133
+ var _a, _b, _c, _d;
46131
46134
  return __awaiter(this, void 0, void 0, function* () {
46132
46135
  const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46136
+ this.interruptedByUser = true;
46133
46137
  const cleanupPromise = this.runCleanupPromise;
46134
46138
  const { cancelableAction } = this;
46135
- const env = DataManager.getSettings('env');
46136
46139
  if (cancelableAction) {
46137
46140
  yield cancelableAction(error);
46138
46141
  }
46139
- else if (this.isProtocolV2() &&
46140
- (DataManager.isBleConnect(env) ||
46141
- DataManager.isBrowserWebUsb(env) ||
46142
- DataManager.isDesktopWebUsb(env)) &&
46143
- this.hasDeviceAcquire()) {
46142
+ else if (this.shouldSendFallbackProtocolCancel()) {
46144
46143
  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
46144
  Log$h.debug('Protocol V2 fallback cancel error', cancelError);
46146
46145
  }));
46147
46146
  }
46148
- yield ((_c = this.commands) === null || _c === void 0 ? void 0 : _c.cancel());
46147
+ else if (!this.hasDeviceAcquire()) {
46148
+ if (this.mainId && ((_c = this.deviceConnector) === null || _c === void 0 ? void 0 : _c.disconnect)) {
46149
+ yield this.deviceConnector.disconnect(this.mainId).catch(disconnectError => {
46150
+ Log$h.debug('Ignored disconnect during user cancel without acquire', disconnectError);
46151
+ });
46152
+ }
46153
+ this.markTransportDisconnected();
46154
+ }
46155
+ yield ((_d = this.commands) === null || _d === void 0 ? void 0 : _d.cancel());
46149
46156
  if (this.runPromise) {
46150
46157
  this.runPromise.reject(error);
46151
46158
  this.runPromise = null;
@@ -46200,6 +46207,26 @@ class Device extends events.exports {
46200
46207
  isUsed() {
46201
46208
  return typeof this.originalDescriptor.session === 'string';
46202
46209
  }
46210
+ wasInterruptedByUser() {
46211
+ return this.interruptedByUser;
46212
+ }
46213
+ throwIfInterruptedByUser() {
46214
+ if (this.interruptedByUser) {
46215
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
46216
+ }
46217
+ }
46218
+ shouldSendFallbackProtocolCancel() {
46219
+ if (!this.hasDeviceAcquire() || !this.isProtocolV2()) {
46220
+ return false;
46221
+ }
46222
+ if (!this.hasOpenProtocolV2UiInteraction()) {
46223
+ return false;
46224
+ }
46225
+ const env = DataManager.getSettings('env');
46226
+ return (DataManager.isBleConnect(env) ||
46227
+ DataManager.isBrowserWebUsb(env) ||
46228
+ DataManager.isDesktopWebUsb(env));
46229
+ }
46203
46230
  hasDeviceAcquire() {
46204
46231
  const env = DataManager.getSettings('env');
46205
46232
  if (DataManager.isBleConnect(env)) {
@@ -48253,6 +48280,8 @@ class DeviceRebootToBootloader extends BaseMethod {
48253
48280
  init() {
48254
48281
  this.useDevicePassphraseState = false;
48255
48282
  this.skipForceUpdateCheck = true;
48283
+ this.unlockPolicy = 'unlock-before-run';
48284
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
48256
48285
  }
48257
48286
  getVersionRange() {
48258
48287
  return {
@@ -48286,6 +48315,8 @@ class DeviceRebootToBoardloader extends BaseMethod {
48286
48315
  init() {
48287
48316
  this.useDevicePassphraseState = false;
48288
48317
  this.skipForceUpdateCheck = true;
48318
+ this.unlockPolicy = 'unlock-before-run';
48319
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
48289
48320
  }
48290
48321
  getVersionRange() {
48291
48322
  return {
@@ -51771,17 +51802,8 @@ const PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS = 1000;
51771
51802
  const PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE = 'FirmwareInstallStatusConflict';
51772
51803
  const PROTOCOL_V2_INSTALL_FAILED_CODE = 'FirmwareInstallFailed';
51773
51804
  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
51805
  const PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT = 512;
51780
51806
  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
51807
  const PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS = new Set(['se03', 'se04']);
51786
51808
  const getProtocolV2ZipEntrySizes = (entry) => {
51787
51809
  var _a;
@@ -51875,14 +51897,8 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
51875
51897
  },
51876
51898
  };
51877
51899
  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
51900
  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;
51901
+ devicePath.toLowerCase() === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH;
51886
51902
  const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map([
51887
51903
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, 'boot'],
51888
51904
  [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, 'app_v1'],
@@ -52008,30 +52024,6 @@ const toProtocolV2FiniteNumber = (value) => {
52008
52024
  }
52009
52025
  return undefined;
52010
52026
  };
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
52027
  const isProtocolV2FirmwareFingerprintValid = (binary, fingerprint) => {
52036
52028
  const expectedFingerprint = normalizeProtocolV2Hex(fingerprint);
52037
52029
  if (!expectedFingerprint)
@@ -52539,7 +52531,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52539
52531
  });
52540
52532
  }
52541
52533
  prepareProtocolV2LocalResourceArchive(binary) {
52542
- var _a;
52543
52534
  return __awaiter(this, void 0, void 0, function* () {
52544
52535
  if (binary.byteLength <= 0 || binary.byteLength > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52545
52536
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP archive size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
@@ -52548,91 +52539,47 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52548
52539
  try {
52549
52540
  zip = yield JSZip__default["default"].loadAsync(binary);
52550
52541
  }
52551
- catch (_b) {
52542
+ catch (_a) {
52552
52543
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource ZIP cannot be parsed', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52553
52544
  }
52554
52545
  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' });
52546
+ const resourceEntries = zipEntries.filter(entry => !entry.dir && entry.name.toLowerCase().endsWith('.okpkg'));
52547
+ if (resourceEntries.length === 0 ||
52548
+ resourceEntries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
52549
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource ZIP has no valid resource package set', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52608
52550
  }
52609
52551
  let totalSize = 0;
52610
52552
  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);
52553
+ const resources = [];
52554
+ const devicePaths = new Set();
52555
+ for (const entry of resourceEntries) {
52556
+ const { compressedSize, uncompressedSize } = getProtocolV2ZipEntrySizes(entry);
52620
52557
  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' });
52558
+ if (compressedSize > binary.byteLength ||
52559
+ uncompressedSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES ||
52560
+ totalSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES) {
52561
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource package size is invalid: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52623
52562
  }
52624
52563
  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' });
52564
+ if (fileBinary.byteLength !== uncompressedSize) {
52565
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource package is incomplete: ${entry.name}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52566
+ }
52567
+ let header;
52568
+ try {
52569
+ header = parseProtocolV2ResourcePackage(fileBinary);
52570
+ }
52571
+ catch (error) {
52572
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource package is invalid: ${entry.name}: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52629
52573
  }
52630
- normalizedFiles.push(Object.assign(Object.assign({}, file), { sha256: digest }));
52631
- materializedEntries.push({ entryName: file.archive_path, binary: fileBinary });
52574
+ const canonicalDevicePath = header.devicePath.toLowerCase();
52575
+ if (devicePaths.has(canonicalDevicePath)) {
52576
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 resource ZIP contains duplicate device path: ${header.devicePath}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52577
+ }
52578
+ devicePaths.add(canonicalDevicePath);
52579
+ materializedEntries.push({ entryName: entry.name, binary: fileBinary });
52580
+ resources.push({ entryName: entry.name, binary: fileBinary, header });
52632
52581
  }
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 };
52582
+ return { binary, materializedEntries, resources };
52636
52583
  });
52637
52584
  }
52638
52585
  prepareProtocolV2ResourceSources() {
@@ -52678,48 +52625,17 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52678
52625
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 prepared resource archive does not match its approved receipt', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52679
52626
  }
52680
52627
  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
52628
  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
- : {})));
52629
+ for (const resource of verifiedArchive.resources) {
52630
+ const source = yield this.openProtocolV2MemorySource(resource.binary);
52631
+ sources.push({
52632
+ name: (_c = resource.entryName.split('/').pop()) !== null && _c !== void 0 ? _c : resource.entryName,
52633
+ source,
52634
+ devicePath: resource.header.devicePath,
52635
+ version: resource.header.version,
52636
+ payloadHash: resource.header.payloadHash,
52637
+ headerHash: resource.header.headerHash,
52638
+ });
52723
52639
  }
52724
52640
  return sources;
52725
52641
  });
@@ -53101,15 +53017,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53101
53017
  if (!((_b = pathInfoRes.message) === null || _b === void 0 ? void 0 : _b.exist) ||
53102
53018
  ((_c = pathInfoRes.message) === null || _c === void 0 ? void 0 : _c.directory) ||
53103
53019
  fileSize === undefined ||
53104
- fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE ||
53020
+ fileSize < PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE ||
53105
53021
  (expectedSize !== undefined && fileSize !== expectedSize)) {
53106
53022
  return null;
53107
53023
  }
53108
53024
  const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
53109
53025
  const chunks = [];
53110
53026
  let offset = 0;
53111
- while (offset < PROTOCOL_V2_OKPP_HEADER_SIZE) {
53112
- const readLen = Math.min(chunkSize, PROTOCOL_V2_OKPP_HEADER_SIZE - offset);
53027
+ while (offset < PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE) {
53028
+ const readLen = Math.min(chunkSize, PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE - offset);
53113
53029
  const res = yield typedCall('FilesystemFileRead', 'FilesystemFile', {
53114
53030
  file: {
53115
53031
  path: filePath,
@@ -53131,7 +53047,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53131
53047
  headerBytes.set(chunk, cursor);
53132
53048
  cursor += chunk.byteLength;
53133
53049
  });
53134
- return parseProtocolV2OkppHeader(headerBytes);
53050
+ try {
53051
+ return parseProtocolV2ResourcePackageHeader(headerBytes, fileSize);
53052
+ }
53053
+ catch (_e) {
53054
+ return null;
53055
+ }
53135
53056
  });
53136
53057
  }
53137
53058
  isProtocolV2ResourceBundleUpToDate(bundle) {
@@ -53357,7 +53278,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53357
53278
  this.protocolV2LastTransferProgressAt = 0;
53358
53279
  let processedSize = 0;
53359
53280
  for (const resource of resourcesToSync) {
53360
- const writePath = resolveProtocolV2ResourceWritePath(resource.devicePath);
53281
+ const writePath = resource.devicePath;
53361
53282
  processedSize = yield this.protocolV2SourceUpdateProcess({
53362
53283
  source: resource.source,
53363
53284
  filePath: writePath,
@@ -54008,7 +53929,7 @@ class PromptWebDeviceAccess extends BaseMethod {
54008
53929
  }
54009
53930
  if (isWebUsbEnv) {
54010
53931
  const usbDevice = device;
54011
- const path = usbDevice.serialNumber;
53932
+ const path = hdShared.resolveOneKeyUsbDevicePath(usbDevice);
54012
53933
  if (!path) {
54013
53934
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.WebDevicePromptAccessError);
54014
53935
  }
@@ -54042,6 +53963,8 @@ class DeviceReboot extends BaseMethod {
54042
53963
  init() {
54043
53964
  this.skipForceUpdateCheck = true;
54044
53965
  this.useDevicePassphraseState = false;
53966
+ this.unlockPolicy = 'unlock-before-run';
53967
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
54045
53968
  this.params = {
54046
53969
  rebootType: this.payload.rebootType,
54047
53970
  reboot_type: this.payload.reboot_type,
@@ -54446,7 +54369,8 @@ class DeviceUploadWallpaper extends BaseMethod {
54446
54369
  });
54447
54370
  this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
54448
54371
  this.params = { jpegBase64, fileName, chunkSize };
54449
- this.unlockPolicy = 'none';
54372
+ this.unlockPolicy = 'unlock-before-run';
54373
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
54450
54374
  this.skipForceUpdateCheck = true;
54451
54375
  this.useDevicePassphraseState = false;
54452
54376
  }
@@ -54602,7 +54526,8 @@ class DeviceUploadNft extends BaseMethod {
54602
54526
  paceMs,
54603
54527
  timeoutMs,
54604
54528
  };
54605
- this.unlockPolicy = 'none';
54529
+ this.unlockPolicy = 'unlock-before-run';
54530
+ this.protocolV2PreUnlockPinType = hdTransport.DeviceSessionPinType.Any;
54606
54531
  this.skipForceUpdateCheck = true;
54607
54532
  this.useDevicePassphraseState = false;
54608
54533
  }
@@ -65282,7 +65207,6 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65282
65207
  if ((_g = method.payload) === null || _g === void 0 ? void 0 : _g.onlyConnectBleDevice) {
65283
65208
  preWarmCallbackTask === null || preWarmCallbackTask === void 0 ? void 0 : preWarmCallbackTask.resolve();
65284
65209
  Log.debug('Call API - only connect ble device: ', device === null || device === void 0 ? void 0 : device.mainId);
65285
- requestQueue.releaseTask(method.responseID);
65286
65210
  return createResponseMessage(method.responseID, true, null);
65287
65211
  }
65288
65212
  Log.debug('Call API - setDevice: ', device.mainId);
@@ -65632,12 +65556,25 @@ function canSkipInitialize(method, device) {
65632
65556
  return true;
65633
65557
  }
65634
65558
  function isRetryableBleProtocolV2ProbeError(method, error) {
65635
- const message = error instanceof Error ? error.message : String(error !== null && error !== void 0 ? error : '');
65559
+ const typedError = error;
65560
+ const message = typeof (typedError === null || typedError === void 0 ? void 0 : typedError.message) === 'string' ? typedError.message : String(error !== null && error !== void 0 ? error : '');
65636
65561
  return (method.payload.connectProtocol === 'V2' &&
65562
+ (typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.RuntimeError &&
65637
65563
  message.includes('Device protocol mismatch') &&
65638
65564
  message.includes('expected V2') &&
65639
65565
  message.includes('did not respond to expected protocol'));
65640
65566
  }
65567
+ function isRetryableBleConnectionError(method, error) {
65568
+ var _a;
65569
+ if ((_a = method.device) === null || _a === void 0 ? void 0 : _a.wasInterruptedByUser()) {
65570
+ return false;
65571
+ }
65572
+ const typedError = error;
65573
+ return ((typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError ||
65574
+ (typedError === null || typedError === void 0 ? void 0 : typedError.errorCode) === hdShared.HardwareErrorCode.BleConnectedError ||
65575
+ isRetryableBleProtocolV2ProbeError(method, error) ||
65576
+ isMissingDetectedProtocolV2Error(method, error));
65577
+ }
65641
65578
  function isMissingDetectedProtocolV2Error(method, error) {
65642
65579
  const typedError = error;
65643
65580
  return (method.payload.connectProtocol === 'V2' &&
@@ -65645,34 +65582,13 @@ function isMissingDetectedProtocolV2Error(method, error) {
65645
65582
  typeof typedError.message === 'string' &&
65646
65583
  typedError.message.includes('Device protocol has not been detected'));
65647
65584
  }
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) {
65585
+ function connectDeviceForBle(method, device, retryCount = 0) {
65673
65586
  var _a;
65674
65587
  return __awaiter(this, void 0, void 0, function* () {
65675
65588
  try {
65589
+ if (device.wasInterruptedByUser()) {
65590
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInterruptedFromUser);
65591
+ }
65676
65592
  if (method.payload.forceProtocolDetection && device.hasDeviceAcquire()) {
65677
65593
  yield device.release();
65678
65594
  }
@@ -65681,31 +65597,9 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
65681
65597
  !device.commands ||
65682
65598
  device.commands.disposed;
65683
65599
  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
- }
65600
+ yield device.acquire(method.payload.connectProtocol, {
65601
+ forceProtocolDetection: method.payload.forceProtocolDetection,
65602
+ });
65709
65603
  }
65710
65604
  if ((_a = method.payload) === null || _a === void 0 ? void 0 : _a.onlyConnectBleDevice) {
65711
65605
  if (shouldAcquire) {
@@ -65732,15 +65626,11 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
65732
65626
  yield device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
65733
65627
  device.markTransportDisconnected();
65734
65628
  }
65735
- if ((err.errorCode === hdShared.HardwareErrorCode.BleTimeoutError ||
65736
- err.errorCode === hdShared.HardwareErrorCode.BleConnectedError ||
65737
- isRetryableBleProtocolV2ProbeError(method, err) ||
65738
- requiresColdReconnect) &&
65739
- retryCount < 6) {
65629
+ if (isRetryableBleConnectionError(method, err) && retryCount < 6) {
65740
65630
  const nextRetry = retryCount + 1;
65741
65631
  Log.debug(`Bluetooth connection will retry, retry count: ${nextRetry}`);
65742
65632
  yield wait(3000);
65743
- yield connectDeviceForBle(method, device, abortSignal, nextRetry);
65633
+ yield connectDeviceForBle(method, device, nextRetry);
65744
65634
  }
65745
65635
  else {
65746
65636
  throw err;
@@ -65822,7 +65712,7 @@ const ensureConnected = (_context, method, connectId, pollingId, abortSignal) =>
65822
65712
  if (abort()) {
65823
65713
  return;
65824
65714
  }
65825
- yield connectDeviceForBle(method, device, abortSignal);
65715
+ yield connectDeviceForBle(method, device);
65826
65716
  }
65827
65717
  resolve(device);
65828
65718
  return;
@@ -66418,14 +66308,12 @@ exports.normalizeSafetyCheckLevel = normalizeSafetyCheckLevel;
66418
66308
  exports.normalizeVersionArray = normalizeVersionArray;
66419
66309
  exports.parseConnectSettings = parseConnectSettings;
66420
66310
  exports.parseMessage = parseMessage;
66421
- exports.parseProtocolV2ResourceManifest = parseProtocolV2ResourceManifest;
66422
66311
  exports.patchFeatures = patchFeatures;
66423
66312
  exports.preloadSessionCache = preloadSessionCache;
66424
66313
  exports.prepareFirmwareUpdateV4MemoryHost = prepareFirmwareUpdateV4MemoryHost;
66425
66314
  exports.projectDeviceStateFeatures = projectFeatures;
66426
66315
  exports.registerFirmwareUpdateHostBinding = registerFirmwareUpdateHostBinding;
66427
66316
  exports.safeThrowError = safeThrowError;
66428
- exports.selectProtocolV2ResourceManifestFiles = selectProtocolV2ResourceManifestFiles;
66429
66317
  exports.setLoggerPostMessage = setLoggerPostMessage;
66430
66318
  exports.supportInputPinOnSoftware = supportInputPinOnSoftware;
66431
66319
  exports.switchTransport = switchTransport;