@onekeyfe/hd-core 1.2.0-alpha.107 → 1.2.0-alpha.109

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 (74) hide show
  1. package/__tests__/DeviceCommands.test.ts +140 -26
  2. package/__tests__/base64Data.test.ts +70 -0
  3. package/__tests__/device-lifecycle-events.test.ts +113 -2
  4. package/__tests__/device-pool-state.test.ts +25 -0
  5. package/__tests__/device-state-mapper.test.ts +4 -4
  6. package/__tests__/device-utils.test.ts +1 -1
  7. package/__tests__/deviceSettings.test.ts +0 -1
  8. package/__tests__/deviceUploadNft.test.ts +33 -4
  9. package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +125 -0
  10. package/__tests__/get-device-state.test.ts +60 -21
  11. package/__tests__/logBlockEvent.test.ts +13 -1
  12. package/__tests__/protocol-v2-resources.test.ts +8 -0
  13. package/__tests__/protocol-v2.test.ts +821 -227
  14. package/__tests__/refresh-device-state.test.ts +3 -1
  15. package/__tests__/resourceBase64Boundary.test.ts +48 -0
  16. package/__tests__/ton-sign-message.test.ts +84 -0
  17. package/dist/api/FirmwareUpdateV4.d.ts +7 -3
  18. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  19. package/dist/api/UploadPortfolio.d.ts +1 -1
  20. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  21. package/dist/api/helpers/base64Data.d.ts +16 -0
  22. package/dist/api/helpers/base64Data.d.ts.map +1 -0
  23. package/dist/api/protocol-v2/DeviceInfoGet.d.ts +1 -1
  24. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
  25. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +2 -3
  26. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
  27. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +2 -3
  28. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  29. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  30. package/dist/core/index.d.ts.map +1 -1
  31. package/dist/device/Device.d.ts +7 -2
  32. package/dist/device/Device.d.ts.map +1 -1
  33. package/dist/device/DeviceCommands.d.ts.map +1 -1
  34. package/dist/device/DevicePool.d.ts.map +1 -1
  35. package/dist/events/logBlockEvent.d.ts.map +1 -1
  36. package/dist/index.d.ts +16 -34
  37. package/dist/index.js +506 -329
  38. package/dist/protocols/protocol-v2/features.d.ts +13 -5
  39. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  40. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  41. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  42. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  43. package/dist/types/api/protocolV2.d.ts +1 -1
  44. package/dist/types/api/protocolV2.d.ts.map +1 -1
  45. package/dist/types/settings.d.ts +4 -19
  46. package/dist/types/settings.d.ts.map +1 -1
  47. package/dist/utils/patch.d.ts +1 -1
  48. package/dist/utils/patch.d.ts.map +1 -1
  49. package/dist/utils/pro2Nft.d.ts +7 -0
  50. package/dist/utils/pro2Nft.d.ts.map +1 -1
  51. package/package.json +6 -4
  52. package/src/api/FirmwareUpdateV4.ts +307 -245
  53. package/src/api/UploadPortfolio.ts +9 -2
  54. package/src/api/helpers/base64Data.ts +85 -0
  55. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +1 -1
  56. package/src/api/protocol-v2/DeviceInfoGet.ts +3 -3
  57. package/src/api/protocol-v2/DeviceUploadNft.ts +56 -8
  58. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +37 -18
  59. package/src/api/ton/TonSignMessage.ts +5 -3
  60. package/src/core/index.ts +6 -2
  61. package/src/data/messages/messages-protocol-v2.json +31 -14
  62. package/src/device/Device.ts +53 -31
  63. package/src/device/DeviceCommands.ts +4 -14
  64. package/src/device/DevicePool.ts +6 -2
  65. package/src/device/DeviceStateMapper.ts +15 -15
  66. package/src/deviceProfile/buildDeviceFeatures.ts +3 -3
  67. package/src/events/logBlockEvent.ts +14 -1
  68. package/src/protocols/protocol-v2/features.ts +22 -5
  69. package/src/protocols/protocol-v2/index.ts +2 -0
  70. package/src/protocols/protocol-v2/resources.ts +9 -46
  71. package/src/types/api/protocolV2.ts +1 -1
  72. package/src/types/settings.ts +4 -19
  73. package/src/utils/deviceSettings.ts +1 -1
  74. package/src/utils/pro2Nft.ts +31 -8
package/dist/index.js CHANGED
@@ -13,9 +13,10 @@ var ByteBuffer = require('bytebuffer');
13
13
  var blake2s = require('@noble/hashes/blake2s');
14
14
  var BigNumber = require('bignumber.js');
15
15
  var JSZip = require('jszip');
16
+ var buffer = require('buffer');
17
+ var jpegJs = require('jpeg-js');
16
18
  var sha3 = require('@noble/hashes/sha3');
17
19
  var blake2b = require('@noble/hashes/blake2b');
18
- var buffer = require('buffer');
19
20
 
20
21
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
21
22
 
@@ -27498,9 +27499,10 @@ var nested = {
27498
27499
  MessageType_FilesystemDirMake: 60809,
27499
27500
  MessageType_FilesystemDirRemove: 60810,
27500
27501
  MessageType_FilesystemFormat: 60811,
27501
- MessageType_DeviceFirmwareUpdateRequest: 61000,
27502
- MessageType_DeviceFirmwareUpdateStatusGet: 61001,
27503
- MessageType_DeviceFirmwareUpdateStatus: 61002,
27502
+ MessageType_DeviceFirmwareUpdateStage: 61000,
27503
+ MessageType_DeviceFirmwareUpdateRequest: 61001,
27504
+ MessageType_DeviceFirmwareUpdateStatusGet: 61002,
27505
+ MessageType_DeviceFirmwareUpdateStatus: 61003,
27504
27506
  MessageType_DeviceSessionGet: 61200,
27505
27507
  MessageType_DeviceSession: 61201,
27506
27508
  MessageType_DeviceSessionAskPin: 61202,
@@ -38002,7 +38004,7 @@ var nested = {
38002
38004
  type: "bytes",
38003
38005
  id: 1
38004
38006
  },
38005
- signing_message: {
38007
+ signning_message: {
38006
38008
  type: "bytes",
38007
38009
  id: 2
38008
38010
  },
@@ -38896,14 +38898,14 @@ var nested = {
38896
38898
  type: "string",
38897
38899
  id: 2
38898
38900
  },
38899
- burn_in_completed: {
38900
- type: "bool",
38901
- id: 3
38902
- },
38903
38901
  factory_test_completed: {
38904
38902
  type: "bool",
38905
38903
  id: 4
38906
38904
  },
38905
+ factory_burn_in_completed: {
38906
+ type: "bool",
38907
+ id: 3
38908
+ },
38907
38909
  manufacture_time: {
38908
38910
  type: "DeviceFactoryInfoManufactureTime",
38909
38911
  id: 5
@@ -38990,7 +38992,7 @@ var nested = {
38990
38992
  }
38991
38993
  }
38992
38994
  },
38993
- DeviceFirmwareUpdateRequest: {
38995
+ DeviceFirmwareUpdateStage: {
38994
38996
  fields: {
38995
38997
  targets: {
38996
38998
  rule: "repeated",
@@ -38999,6 +39001,10 @@ var nested = {
38999
39001
  }
39000
39002
  }
39001
39003
  },
39004
+ DeviceFirmwareUpdateRequest: {
39005
+ fields: {
39006
+ }
39007
+ },
39002
39008
  DeviceFirmwareUpdateRecord: {
39003
39009
  fields: {
39004
39010
  target_id: {
@@ -39180,7 +39186,7 @@ var nested = {
39180
39186
  type: "bool",
39181
39187
  id: 100
39182
39188
  },
39183
- fw: {
39189
+ main_mcu: {
39184
39190
  type: "bool",
39185
39191
  id: 200
39186
39192
  },
@@ -39249,7 +39255,7 @@ var nested = {
39249
39255
  type: "DeviceHardwareInfo",
39250
39256
  id: 100
39251
39257
  },
39252
- fw: {
39258
+ main_mcu: {
39253
39259
  type: "DeviceMainMcuInfo",
39254
39260
  id: 200
39255
39261
  },
@@ -39791,9 +39797,12 @@ var nested = {
39791
39797
  id: 1
39792
39798
  },
39793
39799
  text: {
39794
- rule: "required",
39795
39800
  type: "string",
39796
39801
  id: 2
39802
+ },
39803
+ text_id: {
39804
+ type: "uint32",
39805
+ id: 3
39797
39806
  }
39798
39807
  }
39799
39808
  },
@@ -39824,7 +39833,6 @@ var nested = {
39824
39833
  ViewSignPage: {
39825
39834
  fields: {
39826
39835
  title: {
39827
- rule: "required",
39828
39836
  type: "string",
39829
39837
  id: 1
39830
39838
  },
@@ -39858,13 +39866,16 @@ var nested = {
39858
39866
  options: {
39859
39867
  "default": "LayoutDefault"
39860
39868
  }
39869
+ },
39870
+ title_id: {
39871
+ type: "uint32",
39872
+ id: 8
39861
39873
  }
39862
39874
  }
39863
39875
  },
39864
39876
  ViewVerifyPage: {
39865
39877
  fields: {
39866
39878
  title: {
39867
- rule: "required",
39868
39879
  type: "string",
39869
39880
  id: 1
39870
39881
  },
@@ -39889,6 +39900,14 @@ var nested = {
39889
39900
  value_key: {
39890
39901
  type: "uint32",
39891
39902
  id: 6
39903
+ },
39904
+ title_id: {
39905
+ type: "uint32",
39906
+ id: 7
39907
+ },
39908
+ chain_id: {
39909
+ type: "uint32",
39910
+ id: 8
39892
39911
  }
39893
39912
  }
39894
39913
  },
@@ -40735,7 +40754,9 @@ function parseProtocolV2ResourceManifestFile(value, index) {
40735
40754
  }
40736
40755
  const file = value;
40737
40756
  const archivePath = assertManifestRelativePath(file.archive_path, `files[${index}].archive_path`);
40738
- const originalName = assertManifestRelativePath(file.original_name, `files[${index}].original_name`);
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`);
40739
40760
  if (originalName.includes('/')) {
40740
40761
  throw new Error(`Invalid Pro2 resource manifest files[${index}].original_name`);
40741
40762
  }
@@ -40747,41 +40768,18 @@ function parseProtocolV2ResourceManifestFile(value, index) {
40747
40768
  throw new Error(`Invalid Pro2 resource manifest files[${index}].size`);
40748
40769
  }
40749
40770
  const digest = normalizeHex$1(file.sha256, SHA256_HEX_LENGTH, `files[${index}].sha256`);
40750
- if (file.signed !== true) {
40751
- throw new Error(`Invalid Pro2 resource manifest files[${index}].signed`);
40752
- }
40753
- if (file.sig_algo !== 'ed25519' && file.sig_algo !== 'mldsa65') {
40754
- throw new Error(`Invalid Pro2 resource manifest files[${index}].sig_algo`);
40755
- }
40756
- if (file.payload_version !== null && typeof file.payload_version !== 'string') {
40757
- throw new Error(`Invalid Pro2 resource manifest files[${index}].payload_version`);
40758
- }
40759
40771
  if (!archivePath.endsWith('.okpkg') || !originalName.endsWith('.okpkg')) {
40760
40772
  throw new Error(`Invalid Pro2 resource manifest files[${index}] package extension`);
40761
40773
  }
40762
- return {
40763
- archive_path: archivePath,
40764
- original_name: originalName,
40765
- device_path: devicePath,
40766
- size: Number(file.size),
40767
- sha256: digest,
40768
- signed: true,
40769
- sig_algo: file.sig_algo,
40770
- payload_version: (_a = file.payload_version) !== null && _a !== void 0 ? _a : null,
40771
- };
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 }));
40772
40775
  }
40773
40776
  function parseProtocolV2ResourceManifest(value) {
40774
40777
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
40775
40778
  throw new Error('Invalid Pro2 resource manifest');
40776
40779
  }
40777
40780
  const manifest = value;
40778
- if (manifest.schema !== 1 ||
40779
- manifest.variant !== 'resource' ||
40780
- manifest.device_root !== 'vol0:' ||
40781
- manifest.restore_mode !== 'bootloader_update' ||
40782
- !Array.isArray(manifest.trees) ||
40783
- !Array.isArray(manifest.files)) {
40784
- throw new Error('Invalid Pro2 resource manifest contract');
40781
+ if (!Array.isArray(manifest.files)) {
40782
+ throw new Error('Invalid Pro2 resource manifest files');
40785
40783
  }
40786
40784
  const files = manifest.files.map(parseProtocolV2ResourceManifestFile);
40787
40785
  const devicePaths = new Set(files.map(file => file.device_path));
@@ -40794,27 +40792,6 @@ function parseProtocolV2ResourceManifest(value) {
40794
40792
  throw new Error('Invalid Pro2 resource manifest file set');
40795
40793
  }
40796
40794
  return {
40797
- schema: 1,
40798
- artifact_name: assertManifestString(manifest.artifact_name, 'artifact_name'),
40799
- release_name: assertManifestString(manifest.release_name, 'release_name'),
40800
- variant: 'resource',
40801
- commit: assertManifestString(manifest.commit, 'commit'),
40802
- short_sha: assertManifestString(manifest.short_sha, 'short_sha'),
40803
- timestamp_utc: assertManifestString(manifest.timestamp_utc, 'timestamp_utc'),
40804
- core_version: assertManifestString(manifest.core_version, 'core_version'),
40805
- key_set: assertManifestString(manifest.key_set, 'key_set'),
40806
- device_root: 'vol0:',
40807
- restore_mode: 'bootloader_update',
40808
- trees: manifest.trees.map((tree, index) => {
40809
- if (!tree || typeof tree !== 'object') {
40810
- throw new Error(`Invalid Pro2 resource manifest trees[${index}]`);
40811
- }
40812
- const item = tree;
40813
- return {
40814
- path: assertManifestRelativePath(item.path, `trees[${index}].path`),
40815
- device: assertManifestString(item.device, `trees[${index}].device`),
40816
- };
40817
- }),
40818
40795
  files,
40819
40796
  };
40820
40797
  }
@@ -41474,6 +41451,11 @@ const LogLabelMethod = new Set([
41474
41451
  'fileWrite',
41475
41452
  'fileRead',
41476
41453
  ]);
41454
+ const LogPayloadBlockMethod = new Set([
41455
+ 'deviceUploadNft',
41456
+ 'deviceUploadWallpaper',
41457
+ 'uploadPortfolio',
41458
+ ]);
41477
41459
  const SensitiveLogKeys = new Set([
41478
41460
  'devicestate',
41479
41461
  'entropy',
@@ -41530,7 +41512,10 @@ function getLogBlockLabel(message) {
41530
41512
  return undefined;
41531
41513
  }
41532
41514
  function getSafeLogPayload(value, blockLabel) {
41533
- if (blockLabel && (LogBlockEvent.has(blockLabel) || isSigningMethod(blockLabel))) {
41515
+ if (blockLabel &&
41516
+ (LogBlockEvent.has(blockLabel) ||
41517
+ LogPayloadBlockMethod.has(blockLabel) ||
41518
+ isSigningMethod(blockLabel))) {
41534
41519
  return { method: blockLabel, payload: '[REDACTED]' };
41535
41520
  }
41536
41521
  const redactedValue = redactLogValue(value, new WeakSet());
@@ -42464,7 +42449,7 @@ const getAutoShutDownOptions = (deviceType, protocol) => {
42464
42449
  return withNever([60000, 120000, 300000, 600000], protocol);
42465
42450
  case hdShared.EDeviceType.Pro2:
42466
42451
  case hdShared.EDeviceType.Neo:
42467
- return withNever([60000, 120000, 300000, 600000, 1800000], protocol);
42452
+ return withNever([60000, 120000, 300000, 600000], protocol);
42468
42453
  default:
42469
42454
  return [];
42470
42455
  }
@@ -42723,18 +42708,14 @@ function getCompletePro2NftBasenames(childFiles) {
42723
42708
  function utf8Length(value) {
42724
42709
  return new TextEncoder().encode(value).byteLength;
42725
42710
  }
42726
- function assertImage(name, image, expectedWidth, expectedHeight) {
42727
- if (image.width !== expectedWidth || image.height !== expectedHeight) {
42728
- throw invalidParameter$1(`Pro2 NFT ${name} dimensions must be ${expectedWidth}x${expectedHeight}.`);
42711
+ function buildPro2NftBundleFromEncodedImages(options) {
42712
+ const { image, thumbnail, title, subtitle, timestampMs } = options;
42713
+ if (!(image instanceof Uint8Array) || image.byteLength === 0) {
42714
+ throw invalidParameter$1('Parameter [image] must contain encoded NFT image data.');
42729
42715
  }
42730
- if (!(image.rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(image.rgba)) {
42731
- throw invalidParameter$1(`Parameter [${name}.rgba] must be an ArrayBuffer or Uint8Array.`);
42716
+ if (!(thumbnail instanceof Uint8Array) || thumbnail.byteLength === 0) {
42717
+ throw invalidParameter$1('Parameter [thumbnail] must contain encoded NFT thumbnail data.');
42732
42718
  }
42733
- }
42734
- function buildPro2NftBundle(options) {
42735
- const { image, thumbnail, title, subtitle, timestampMs } = options;
42736
- assertImage('image', image, PRO2_NFT_IMAGE_WIDTH, PRO2_NFT_IMAGE_HEIGHT);
42737
- assertImage('thumbnail', thumbnail, PRO2_NFT_THUMBNAIL_WIDTH, PRO2_NFT_THUMBNAIL_HEIGHT);
42738
42719
  const titleLength = typeof title === 'string' ? utf8Length(title) : 0;
42739
42720
  const subtitleLength = typeof subtitle === 'string' ? utf8Length(subtitle) : Number.POSITIVE_INFINITY;
42740
42721
  if (titleLength < 1 || titleLength > 63) {
@@ -42746,17 +42727,15 @@ function buildPro2NftBundle(options) {
42746
42727
  if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) {
42747
42728
  throw invalidParameter$1('Parameter [timestampMs] must be a positive safe integer.');
42748
42729
  }
42749
- const encodedImage = encodePro2Image(Object.assign(Object.assign({}, image), { alphaMode: 'black-background' })).data;
42750
- const encodedThumbnail = encodePro2Image(Object.assign(Object.assign({}, thumbnail), { alphaMode: 'black-background' })).data;
42751
42730
  const metadata = new TextEncoder().encode(JSON.stringify({ title, subtitle }));
42752
42731
  if (metadata.byteLength === 0 || metadata.byteLength > 512) {
42753
42732
  throw invalidParameter$1('Pro2 NFT metadata must contain 1 to 512 UTF-8 bytes.');
42754
42733
  }
42755
- const hash8 = utils.bytesToHex(blake2s.blake2s(encodedImage)).slice(0, 8);
42734
+ const hash8 = utils.bytesToHex(blake2s.blake2s(image)).slice(0, 8);
42756
42735
  return {
42757
42736
  basename: `nft-${hash8}-${timestampMs}`,
42758
- image: encodedImage,
42759
- thumbnail: encodedThumbnail,
42737
+ image,
42738
+ thumbnail,
42760
42739
  metadata,
42761
42740
  };
42762
42741
  }
@@ -43276,9 +43255,13 @@ class DevicePool extends events.exports {
43276
43255
  }
43277
43256
  static _refreshProtocolV2DiscoveryState(device) {
43278
43257
  return __awaiter(this, void 0, void 0, function* () {
43279
- yield device.getDeviceState({ refreshSections: ['status'] });
43258
+ yield device.getDeviceState({
43259
+ refreshSections: ['status'],
43260
+ });
43280
43261
  try {
43281
- yield device.getDeviceState({ refreshSections: ['settings'] });
43262
+ yield device.getDeviceState({
43263
+ refreshSections: ['settings'],
43264
+ });
43282
43265
  }
43283
43266
  catch (error) {
43284
43267
  Log$j.debug('Unable to refresh Protocol V2 device label during discovery', error);
@@ -43720,9 +43703,6 @@ class DeviceCommands {
43720
43703
  const promise = this.transport.call(this.mainId, type, msg !== null && msg !== void 0 ? msg : {}, options);
43721
43704
  this.callPromise = promise;
43722
43705
  const res = yield promise;
43723
- if (!shouldReduceDebug) {
43724
- LogCore.debug('[DeviceCommands] [call] Received', res.type, hdTransport.getSafeTransportLogPayload(res.message, res.type));
43725
- }
43726
43706
  return res;
43727
43707
  }
43728
43708
  catch (error) {
@@ -43815,12 +43795,10 @@ class DeviceCommands {
43815
43795
  if (!shouldReduceDebugForCall(callType)) {
43816
43796
  Log$h.debug('_filterCommonTypes: ', {
43817
43797
  request: callType,
43818
- response: callType === 'DeviceFirmwareUpdateStatusGet'
43819
- ? {
43820
- type: res.type,
43821
- message: hdTransport.getSafeTransportLogPayload(res.message, res.type),
43822
- }
43823
- : res.type,
43798
+ response: {
43799
+ type: res.type,
43800
+ message: hdTransport.getSafeTransportLogPayload(res.message, res.type),
43801
+ },
43824
43802
  });
43825
43803
  }
43826
43804
  }
@@ -44226,6 +44204,7 @@ const getProtocolV2SeState = (se) => {
44226
44204
  }
44227
44205
  };
44228
44206
  const getProtocolV2SeType = (se) => normalizeEnumValue(hdTransport.DeviceSeType, se === null || se === void 0 ? void 0 : se.type);
44207
+ const isLegacyProtocolV2ProtocolInfo = (protocolInfo) => Object.prototype.hasOwnProperty.call(protocolInfo, 'protobuf_definition');
44229
44208
  const parseProtocolV2BuildFingerprint = (buildFingerprint) => {
44230
44209
  if (!buildFingerprint)
44231
44210
  return null;
@@ -44240,19 +44219,27 @@ const parseProtocolV2BuildFingerprint = (buildFingerprint) => {
44240
44219
  }
44241
44220
  return { binary, version, commit, environment, buildType };
44242
44221
  };
44243
- const getProtocolV2RuntimeMode = (protocolInfo) => {
44244
- var _a;
44222
+ const getProtocolV2RuntimeMode = (protocolInfo, deviceInfo) => {
44223
+ var _a, _b, _c, _d;
44245
44224
  const binary = (_a = parseProtocolV2BuildFingerprint(protocolInfo.build_fingerprint)) === null || _a === void 0 ? void 0 : _a.binary;
44246
44225
  if (binary === 'application')
44247
44226
  return 'normal';
44248
- return binary;
44227
+ if (binary)
44228
+ return binary;
44229
+ if (isLegacyProtocolV2ProtocolInfo(protocolInfo) && !((_b = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _b === void 0 ? void 0 : _b.application)) {
44230
+ if ((_c = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _c === void 0 ? void 0 : _c.romloader)
44231
+ return 'romloader';
44232
+ if ((_d = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.main_mcu) === null || _d === void 0 ? void 0 : _d.bootloader)
44233
+ return 'bootloader';
44234
+ }
44235
+ return undefined;
44249
44236
  };
44250
44237
  const PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE = 60602;
44251
44238
  const supportsProtocolV2Message = (protocolInfo, messageType) => protocolInfo.supported_messages.includes(messageType);
44252
44239
  const PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST = {
44253
44240
  targets: {
44254
44241
  hw: true,
44255
- fw: true,
44242
+ main_mcu: true,
44256
44243
  coprocessor: true,
44257
44244
  },
44258
44245
  types: {
@@ -44263,7 +44250,7 @@ const PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST = {
44263
44250
  const PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST = {
44264
44251
  targets: {
44265
44252
  hw: true,
44266
- fw: true,
44253
+ main_mcu: true,
44267
44254
  coprocessor: true,
44268
44255
  se1: true,
44269
44256
  se2: true,
@@ -44278,7 +44265,7 @@ const PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST = {
44278
44265
  const PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST = {
44279
44266
  targets: {
44280
44267
  hw: true,
44281
- fw: true,
44268
+ main_mcu: true,
44282
44269
  coprocessor: true,
44283
44270
  se1: true,
44284
44271
  se2: true,
@@ -44545,11 +44532,11 @@ const mapProtocolV2DeviceInfoToState = (info, mode = 'unknown') => {
44545
44532
  }
44546
44533
  : { mode },
44547
44534
  versions: definedEntries({
44548
- firmware: imageVersion((_d = info.fw) === null || _d === void 0 ? void 0 : _d.application),
44549
- applicationP1: imageVersion((_e = info.fw) === null || _e === void 0 ? void 0 : _e.application),
44550
- applicationP2: imageVersion((_f = info.fw) === null || _f === void 0 ? void 0 : _f.application_data),
44551
- bootloader: imageVersion((_g = info.fw) === null || _g === void 0 ? void 0 : _g.bootloader),
44552
- board: imageVersion((_h = info.fw) === null || _h === void 0 ? void 0 : _h.romloader),
44535
+ firmware: imageVersion((_d = info.main_mcu) === null || _d === void 0 ? void 0 : _d.application),
44536
+ applicationP1: imageVersion((_e = info.main_mcu) === null || _e === void 0 ? void 0 : _e.application),
44537
+ applicationP2: imageVersion((_f = info.main_mcu) === null || _f === void 0 ? void 0 : _f.application_data),
44538
+ bootloader: imageVersion((_g = info.main_mcu) === null || _g === void 0 ? void 0 : _g.bootloader),
44539
+ board: imageVersion((_h = info.main_mcu) === null || _h === void 0 ? void 0 : _h.romloader),
44553
44540
  ble: imageVersion((_j = info.coprocessor) === null || _j === void 0 ? void 0 : _j.application),
44554
44541
  se01: imageVersion((_k = info.se1) === null || _k === void 0 ? void 0 : _k.application),
44555
44542
  se02: imageVersion((_l = info.se2) === null || _l === void 0 ? void 0 : _l.application),
@@ -44561,16 +44548,16 @@ const mapProtocolV2DeviceInfoToState = (info, mode = 'unknown') => {
44561
44548
  se04Boot: imageVersion((_s = info.se4) === null || _s === void 0 ? void 0 : _s.bootloader),
44562
44549
  }),
44563
44550
  verification: definedEntries({
44564
- firmwareBuildId: imageBuildId((_t = info.fw) === null || _t === void 0 ? void 0 : _t.application),
44565
- firmwareHash: imageHash((_u = info.fw) === null || _u === void 0 ? void 0 : _u.application),
44566
- applicationP1BuildId: imageBuildId((_v = info.fw) === null || _v === void 0 ? void 0 : _v.application),
44567
- applicationP1Hash: imageHash((_w = info.fw) === null || _w === void 0 ? void 0 : _w.application),
44568
- applicationP2BuildId: imageBuildId((_x = info.fw) === null || _x === void 0 ? void 0 : _x.application_data),
44569
- applicationP2Hash: imageHash((_y = info.fw) === null || _y === void 0 ? void 0 : _y.application_data),
44570
- bootloaderBuildId: imageBuildId((_z = info.fw) === null || _z === void 0 ? void 0 : _z.bootloader),
44571
- bootloaderHash: imageHash((_0 = info.fw) === null || _0 === void 0 ? void 0 : _0.bootloader),
44572
- boardBuildId: imageBuildId((_1 = info.fw) === null || _1 === void 0 ? void 0 : _1.romloader),
44573
- boardHash: imageHash((_2 = info.fw) === null || _2 === void 0 ? void 0 : _2.romloader),
44551
+ firmwareBuildId: imageBuildId((_t = info.main_mcu) === null || _t === void 0 ? void 0 : _t.application),
44552
+ firmwareHash: imageHash((_u = info.main_mcu) === null || _u === void 0 ? void 0 : _u.application),
44553
+ applicationP1BuildId: imageBuildId((_v = info.main_mcu) === null || _v === void 0 ? void 0 : _v.application),
44554
+ applicationP1Hash: imageHash((_w = info.main_mcu) === null || _w === void 0 ? void 0 : _w.application),
44555
+ applicationP2BuildId: imageBuildId((_x = info.main_mcu) === null || _x === void 0 ? void 0 : _x.application_data),
44556
+ applicationP2Hash: imageHash((_y = info.main_mcu) === null || _y === void 0 ? void 0 : _y.application_data),
44557
+ bootloaderBuildId: imageBuildId((_z = info.main_mcu) === null || _z === void 0 ? void 0 : _z.bootloader),
44558
+ bootloaderHash: imageHash((_0 = info.main_mcu) === null || _0 === void 0 ? void 0 : _0.bootloader),
44559
+ boardBuildId: imageBuildId((_1 = info.main_mcu) === null || _1 === void 0 ? void 0 : _1.romloader),
44560
+ boardHash: imageHash((_2 = info.main_mcu) === null || _2 === void 0 ? void 0 : _2.romloader),
44574
44561
  bleBuildId: imageBuildId((_3 = info.coprocessor) === null || _3 === void 0 ? void 0 : _3.application),
44575
44562
  bleHash: imageHash((_4 = info.coprocessor) === null || _4 === void 0 ? void 0 : _4.application),
44576
44563
  se01BuildId: imageBuildId((_5 = info.se1) === null || _5 === void 0 ? void 0 : _5.application),
@@ -45247,6 +45234,7 @@ class Device extends events.exports {
45247
45234
  yield this.commands.dispose(false);
45248
45235
  }
45249
45236
  this.commands = new DeviceCommands(this, (_g = this.mainId) !== null && _g !== void 0 ? _g : '');
45237
+ this.invalidateProtocolV2RuntimeState();
45250
45238
  }
45251
45239
  catch (error) {
45252
45240
  if (options === null || options === void 0 ? void 0 : options.forceProtocolDetection) {
@@ -45641,8 +45629,7 @@ class Device extends events.exports {
45641
45629
  commands: this.commands,
45642
45630
  timeoutMs: options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs,
45643
45631
  });
45644
- const features = yield this.probeProtocolV2RuntimeState(deviceInfo, options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs);
45645
- Log$g.debug('Protocol V2 features:', features);
45632
+ yield this.probeProtocolV2RuntimeState(deviceInfo, options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs);
45646
45633
  }
45647
45634
  catch (error) {
45648
45635
  Log$g.error('Protocol V2 initialization failed:', error);
@@ -45664,7 +45651,7 @@ class Device extends events.exports {
45664
45651
  });
45665
45652
  }
45666
45653
  getDeviceState(params = {}) {
45667
- var _a, _b, _c;
45654
+ var _a, _b, _c, _d;
45668
45655
  return __awaiter(this, void 0, void 0, function* () {
45669
45656
  const refresh = new Set((_a = params.refreshSections) !== null && _a !== void 0 ? _a : []);
45670
45657
  const getProtocolV2DeviceInfoRequest = () => {
@@ -45712,9 +45699,12 @@ class Device extends events.exports {
45712
45699
  }
45713
45700
  }
45714
45701
  if (refresh.has('status') && !initializedWithDeviceInfo) {
45715
- yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo);
45702
+ const cachedMode = (_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode;
45703
+ yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo, undefined, {
45704
+ forceRuntimeContextRefresh: cachedMode === 'bootloader' || cachedMode === 'romloader',
45705
+ });
45716
45706
  }
45717
- if (refresh.has('settings') && ((_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode) === 'normal') {
45707
+ if (refresh.has('settings') && ((_d = this.state) === null || _d === void 0 ? void 0 : _d.status.mode) === 'normal') {
45718
45708
  const { message } = yield this.commands.typedCall('DeviceSettingsGet', 'DeviceSettings', {});
45719
45709
  this.updateState(mapDeviceSettingsToState(message), 'settings-read');
45720
45710
  }
@@ -45751,9 +45741,10 @@ class Device extends events.exports {
45751
45741
  source,
45752
45742
  changedKeys: result.changedKeys,
45753
45743
  };
45754
- Log$g.debug('Device state patch committed', {
45744
+ Log$g.debug('Device state updated', {
45755
45745
  source,
45756
- keys: result.changedKeys,
45746
+ revision: result.revision,
45747
+ changedKeyCount: result.changedKeys.length,
45757
45748
  });
45758
45749
  this.emit(DEVICE.STATE, this, event);
45759
45750
  if (result.state.protocol === 'V1') {
@@ -45772,12 +45763,14 @@ class Device extends events.exports {
45772
45763
  this.updateState(mapFeaturesToState(normalized), source);
45773
45764
  return this.features;
45774
45765
  }
45775
- ensureProtocolV2RuntimeContext(timeoutMs) {
45766
+ ensureProtocolV2RuntimeContext(timeoutMs, options) {
45776
45767
  var _a, _b, _c, _d;
45777
45768
  return __awaiter(this, void 0, void 0, function* () {
45778
- const cachedProtocolInfo = (_a = this.protocolV2RuntimeContext) !== null && _a !== void 0 ? _a : (!this.protocolV2StateNeedsReload
45779
- ? (_d = (_c = (_b = this.state) === null || _b === void 0 ? void 0 : _b.raw) === null || _c === void 0 ? void 0 : _c.protocolV2ProtocolInfo) !== null && _d !== void 0 ? _d : undefined
45780
- : undefined);
45769
+ const cachedProtocolInfo = (options === null || options === void 0 ? void 0 : options.forceRefresh) === true
45770
+ ? undefined
45771
+ : (_a = this.protocolV2RuntimeContext) !== null && _a !== void 0 ? _a : (!this.protocolV2StateNeedsReload
45772
+ ? (_d = (_c = (_b = this.state) === null || _b === void 0 ? void 0 : _b.raw) === null || _c === void 0 ? void 0 : _c.protocolV2ProtocolInfo) !== null && _d !== void 0 ? _d : undefined
45773
+ : undefined);
45781
45774
  if (cachedProtocolInfo) {
45782
45775
  this.protocolV2RuntimeContext = cachedProtocolInfo;
45783
45776
  return cachedProtocolInfo;
@@ -45812,12 +45805,15 @@ class Device extends events.exports {
45812
45805
  }
45813
45806
  });
45814
45807
  }
45815
- probeProtocolV2RuntimeState(deviceInfo, timeoutMs) {
45808
+ probeProtocolV2RuntimeState(deviceInfo, timeoutMs, options) {
45816
45809
  var _a, _b, _c;
45817
45810
  return __awaiter(this, void 0, void 0, function* () {
45818
- const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs);
45819
- const runtimeMode = getProtocolV2RuntimeMode(protocolInfo);
45811
+ const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs, {
45812
+ forceRefresh: options === null || options === void 0 ? void 0 : options.forceRuntimeContextRefresh,
45813
+ });
45820
45814
  const runtimeDeviceInfo = deviceInfo !== null && deviceInfo !== void 0 ? deviceInfo : (_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.raw) === null || _b === void 0 ? void 0 : _b.protocolV2DeviceInfo;
45815
+ const runtimeMode = getProtocolV2RuntimeMode(protocolInfo, runtimeDeviceInfo);
45816
+ const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
45821
45817
  const protocolV2DeviceType = runtimeDeviceInfo
45822
45818
  ? resolveProtocolV2DeviceIdentity((_c = runtimeDeviceInfo.hw) === null || _c === void 0 ? void 0 : _c.Device_type).deviceType
45823
45819
  : this.getCurrentDeviceType();
@@ -45826,7 +45822,8 @@ class Device extends events.exports {
45826
45822
  protocolV2DeviceType !== hdShared.EDeviceType.Neo) {
45827
45823
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, 'Protocol V2 romloader mode is only supported for Pro2 and Neo.');
45828
45824
  }
45829
- const deviceStatusSupported = supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
45825
+ const deviceStatusSupported = legacyProtocolInfo ||
45826
+ supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
45830
45827
  if (runtimeMode === 'bootloader' || runtimeMode === 'romloader') {
45831
45828
  return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
45832
45829
  }
@@ -45874,8 +45871,7 @@ class Device extends events.exports {
45874
45871
  const previousStatus = (_d = (_c = this.state) === null || _c === void 0 ? void 0 : _c.raw) === null || _d === void 0 ? void 0 : _d.protocolV2DeviceStatus;
45875
45872
  return this.updateProtocolV2Features(previousDeviceInfo, Object.assign(Object.assign({}, previousStatus), status));
45876
45873
  }
45877
- markTransportDisconnected() {
45878
- this.deviceAcquired = false;
45874
+ invalidateProtocolV2RuntimeState() {
45879
45875
  if (!this.isProtocolV2())
45880
45876
  return;
45881
45877
  this.protocolV2StateNeedsReload = true;
@@ -45884,6 +45880,10 @@ class Device extends events.exports {
45884
45880
  this.protocolV2RuntimeContextRequestToken = undefined;
45885
45881
  this.clearPreInitialized();
45886
45882
  }
45883
+ markTransportDisconnected() {
45884
+ this.deviceAcquired = false;
45885
+ this.invalidateProtocolV2RuntimeState();
45886
+ }
45887
45887
  invalidateAfterWipe() {
45888
45888
  const deviceId = this.getCurrentDeviceId();
45889
45889
  if (deviceId) {
@@ -45893,10 +45893,7 @@ class Device extends events.exports {
45893
45893
  if (this.originalDescriptor.path !== deviceId) {
45894
45894
  deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
45895
45895
  }
45896
- this.protocolV2StateNeedsReload = true;
45897
- this.protocolV2RuntimeContext = undefined;
45898
- this.protocolV2RuntimeContextPromise = undefined;
45899
- this.protocolV2RuntimeContextRequestToken = undefined;
45896
+ this.invalidateProtocolV2RuntimeState();
45900
45897
  }
45901
45898
  this.passphraseState = undefined;
45902
45899
  this.stateStore = new DeviceStateStore();
@@ -45906,11 +45903,7 @@ class Device extends events.exports {
45906
45903
  markProtocolV2Reboot(rebootType) {
45907
45904
  if (!this.isProtocolV2())
45908
45905
  return;
45909
- this.protocolV2StateNeedsReload = true;
45910
- this.protocolV2RuntimeContext = undefined;
45911
- this.protocolV2RuntimeContextPromise = undefined;
45912
- this.protocolV2RuntimeContextRequestToken = undefined;
45913
- this.clearPreInitialized();
45906
+ this.invalidateProtocolV2RuntimeState();
45914
45907
  let loaderMode;
45915
45908
  if (rebootType === hdTransport.DeviceRebootType.Bootloader) {
45916
45909
  loaderMode = 'bootloader';
@@ -45966,6 +45959,7 @@ class Device extends events.exports {
45966
45959
  if (device.features) {
45967
45960
  this._updateFeatures(device.features);
45968
45961
  }
45962
+ this.invalidateProtocolV2RuntimeState();
45969
45963
  }
45970
45964
  run(fn, options) {
45971
45965
  return __awaiter(this, void 0, void 0, function* () {
@@ -51652,7 +51646,6 @@ const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 90 * 1000;
51652
51646
  const PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT = 3 * 60 * 1000;
51653
51647
  const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
51654
51648
  const PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT = 15 * 1000;
51655
- const PROTOCOL_V2_START_UPDATE_TIMEOUT = 3 * 60 * 1000;
51656
51649
  const PROTOCOL_V2_INSTALL_TIMEOUT = 8 * 60 * 1000;
51657
51650
  const PROTOCOL_V2_MISSING_TARGET_STATUS_GRACE_TIMEOUT = 30 * 1000;
51658
51651
  const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
@@ -51675,6 +51668,10 @@ const PROTOCOL_V2_OKPP_HASH_SIZE = 64;
51675
51668
  const PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES = 1024 * 1024;
51676
51669
  const PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT = 512;
51677
51670
  const PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES = 256 * 1024 * 1024;
51671
+ const getProtocolV2LocalResourceArchivePath = (entryName) => {
51672
+ const match = entryName.match(/(?:^|\/)((?:bundles\/|loaders\/(?:bootloader|rom)\/).+\.okpkg)$/iu);
51673
+ return match === null || match === void 0 ? void 0 : match[1];
51674
+ };
51678
51675
  const PROTOCOL_V2_NEO_UNSUPPORTED_TARGETS = new Set(['se03', 'se04']);
51679
51676
  const getProtocolV2ZipEntrySizes = (entry) => {
51680
51677
  var _a;
@@ -51954,6 +51951,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51954
51951
  this.protocolV2BootResourceStagingSafe = false;
51955
51952
  this.protocolV2CompletedTargetVersions = new Map();
51956
51953
  this.protocolV2FinalStatusVerified = false;
51954
+ this.protocolV2InstallBaselineVersions = new Map();
51957
51955
  }
51958
51956
  getSupportedProtocols() {
51959
51957
  return ['V2'];
@@ -52131,6 +52129,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52131
52129
  return __awaiter(this, void 0, void 0, function* () {
52132
52130
  yield this.captureProtocolV2PhysicalIdentity();
52133
52131
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
52132
+ this.protocolV2InstallBaselineVersions =
52133
+ this.getProtocolV2ObservableTargetVersions(deviceFeatures);
52134
+ this.protocolV2LastRuntimeProbeFeatures = undefined;
52134
52135
  const currentDeviceType = this.device.getCurrentDeviceType();
52135
52136
  const capabilityDeviceType = currentDeviceType === hdShared.EDeviceType.Pro2 || currentDeviceType === hdShared.EDeviceType.Neo
52136
52137
  ? currentDeviceType
@@ -52139,9 +52140,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52139
52140
  const deviceFirmwareType = getFirmwareType(deviceFeatures);
52140
52141
  const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
52141
52142
  this.validateExpectedTargetVersions();
52143
+ const wantsResources = !!((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'));
52142
52144
  if (!this.params.preparedPlan &&
52143
52145
  this.params.resourceArchiveBinary &&
52144
- ((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'))) {
52146
+ ((_c = this.params.targetsToUpdate) === null || _c === void 0 ? void 0 : _c.includes('resource'))) {
52145
52147
  const localMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
52146
52148
  features: deviceFeatures,
52147
52149
  firmwareType,
@@ -52153,14 +52155,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52153
52155
  localMemoryHost.release();
52154
52156
  }
52155
52157
  }
52156
- const hasPreparedComponentArtifacts = Object.values((_c = this.params.componentArtifacts) !== null && _c !== void 0 ? _c : {}).some(Boolean);
52158
+ const hasPreparedComponentArtifacts = Object.values((_d = this.params.componentArtifacts) !== null && _d !== void 0 ? _d : {}).some(Boolean);
52157
52159
  if (this.params.preparedPlan || hasPreparedComponentArtifacts) {
52158
52160
  return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
52159
52161
  }
52160
- const wantsResources = !!((_d = this.params.targetsToUpdate) === null || _d === void 0 ? void 0 : _d.includes('resource'));
52161
52162
  let fwBinaryMap = [];
52162
52163
  let bootloaderBinary = null;
52163
52164
  let installItems;
52165
+ let resourceMemoryHost;
52164
52166
  try {
52165
52167
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
52166
52168
  fwBinaryMap = this.collectExplicitTargetBinaries();
@@ -52173,20 +52175,19 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52173
52175
  const needsRemoteFirmware = ((_e = this.params.targetsToUpdate) === null || _e === void 0 ? void 0 : _e.length)
52174
52176
  ? missingFirmwareTargets.length > 0
52175
52177
  : explicitInstallItems.length === 0;
52176
- if (wantsResources) {
52177
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive must be provided through a local or external PreparedPlan', {
52178
- firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
52179
- });
52180
- }
52181
- if (needsRemoteFirmware &&
52178
+ const needsSdkManagedArtifacts = needsRemoteFirmware || wantsResources;
52179
+ if (needsSdkManagedArtifacts &&
52182
52180
  (this.params.artifactReader ||
52183
52181
  DataManager.getSettings('firmwareManifestMode') === 'external-only')) {
52184
52182
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware artifacts must be prepared by the external firmware host', {
52185
52183
  firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
52186
52184
  });
52187
52185
  }
52188
- if (needsRemoteFirmware) {
52189
- yield DataManager.forceReloadData();
52186
+ if (needsSdkManagedArtifacts) {
52187
+ yield DataManager.forceReloadData({
52188
+ requireResources: wantsResources,
52189
+ resourceDeviceType: capabilityDeviceType === hdShared.EDeviceType.Neo ? hdShared.EDeviceType.Neo : hdShared.EDeviceType.Pro2,
52190
+ });
52190
52191
  }
52191
52192
  if (needsRemoteFirmware) {
52192
52193
  const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures, explicitInstallItems);
@@ -52206,9 +52207,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52206
52207
  targetId: item.targetId,
52207
52208
  }));
52208
52209
  }
52210
+ if (wantsResources) {
52211
+ this.params.resourceArchiveBinary = yield this.downloadRemoteProtocolV2ResourceArchive(deviceFeatures);
52212
+ resourceMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
52213
+ features: deviceFeatures,
52214
+ firmwareType,
52215
+ availableInstallItems: installItems !== null && installItems !== void 0 ? installItems : explicitInstallItems,
52216
+ });
52217
+ }
52209
52218
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
52210
52219
  }
52211
52220
  catch (err) {
52221
+ resourceMemoryHost === null || resourceMemoryHost === void 0 ? void 0 : resourceMemoryHost.release();
52212
52222
  if (typeof err === 'object' &&
52213
52223
  err !== null &&
52214
52224
  'params' in err &&
@@ -52220,6 +52230,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52220
52230
  }
52221
52231
  throw normalizeFirmwarePreparationError(err);
52222
52232
  }
52233
+ if (resourceMemoryHost) {
52234
+ try {
52235
+ return yield this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType, false);
52236
+ }
52237
+ finally {
52238
+ resourceMemoryHost.release();
52239
+ }
52240
+ }
52223
52241
  if (!bootloaderBinary && fwBinaryMap.length === 0 && !(installItems === null || installItems === void 0 ? void 0 : installItems.length)) {
52224
52242
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
52225
52243
  }
@@ -52319,13 +52337,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52319
52337
  return installSources;
52320
52338
  });
52321
52339
  }
52322
- prepareProtocolV2LocalMemoryHost({ features, firmwareType, }) {
52340
+ prepareProtocolV2LocalMemoryHost({ features, firmwareType, availableInstallItems = this.buildProtocolV2InstallItems({
52341
+ bootloaderBinary: this.prepareBootloaderBinary(),
52342
+ fwBinaryMap: this.collectExplicitTargetBinaries(),
52343
+ }), }) {
52323
52344
  var _a, _b;
52324
52345
  return __awaiter(this, void 0, void 0, function* () {
52325
- const availableInstallItems = this.buildProtocolV2InstallItems({
52326
- bootloaderBinary: this.prepareBootloaderBinary(),
52327
- fwBinaryMap: this.collectExplicitTargetBinaries(),
52328
- });
52329
52346
  const requestedComponentTargets = new Set(((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter((target) => target !== 'resource' && target !== 'boot_resources'));
52330
52347
  const localComponentTargets = new Set(availableInstallItems.flatMap(item => {
52331
52348
  const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
@@ -52429,60 +52446,63 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52429
52446
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unsafe entry path', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52430
52447
  }
52431
52448
  const entries = zipEntries.filter(entry => !entry.dir);
52432
- if (entries.length === 0 || entries.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT + 1) {
52449
+ if (entries.length === 0) {
52433
52450
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP entry set is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52434
52451
  }
52435
- let declaredUncompressedSize = 0;
52436
- let declaredCompressedSize = 0;
52437
- for (const entry of entries) {
52438
- const sizes = getProtocolV2ZipEntrySizes(entry);
52439
- declaredCompressedSize += sizes.compressedSize;
52440
- declaredUncompressedSize += sizes.uncompressedSize;
52441
- const entryLimit = entry.name === 'manifest.json'
52442
- ? PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES
52443
- : PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES;
52444
- if (sizes.uncompressedSize > entryLimit ||
52445
- declaredCompressedSize > binary.byteLength ||
52446
- declaredUncompressedSize >
52447
- PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES + PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52448
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP declared size exceeds the allowed limit', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52452
+ const manifestEntry = entries.find(entry => entry.name.split('/').pop() === 'manifest.json');
52453
+ let manifestBinary;
52454
+ let manifestDirectory = '';
52455
+ let selectedFiles;
52456
+ if (manifestEntry) {
52457
+ if (getProtocolV2ZipEntrySizes(manifestEntry).uncompressedSize >
52458
+ PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52459
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52449
52460
  }
52461
+ manifestBinary = yield manifestEntry.async('arraybuffer');
52462
+ if (manifestBinary.byteLength <= 0 ||
52463
+ manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52464
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52465
+ }
52466
+ let manifestValue;
52467
+ try {
52468
+ manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
52469
+ }
52470
+ catch (error) {
52471
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52472
+ }
52473
+ selectedFiles = selectProtocolV2ResourceManifestFiles({
52474
+ manifest: parseProtocolV2ResourceManifest(manifestValue),
52475
+ targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
52476
+ });
52477
+ manifestDirectory = manifestEntry.name.slice(0, -'manifest.json'.length);
52450
52478
  }
52451
- const manifestEntry = zip.file('manifest.json');
52452
- if (!manifestEntry) {
52453
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no manifest.json', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52454
- }
52455
- const manifestBinary = yield manifestEntry.async('arraybuffer');
52456
- if (manifestBinary.byteLength <= 0 ||
52457
- manifestBinary.byteLength > PROTOCOL_V2_RESOURCE_MANIFEST_MAX_BYTES) {
52458
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource manifest size is invalid', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52459
- }
52460
- let manifestValue;
52461
- try {
52462
- manifestValue = JSON.parse(new TextDecoder().decode(manifestBinary));
52463
- }
52464
- catch (error) {
52465
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource manifest is invalid: ${String(error)}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52479
+ else {
52480
+ selectedFiles = entries.flatMap(entry => {
52481
+ var _a;
52482
+ const archivePath = getProtocolV2LocalResourceArchivePath(entry.name);
52483
+ if (!archivePath)
52484
+ return [];
52485
+ return [
52486
+ {
52487
+ archive_path: archivePath,
52488
+ original_name: (_a = archivePath.split('/').pop()) !== null && _a !== void 0 ? _a : archivePath,
52489
+ device_path: `vol0:/${archivePath}`,
52490
+ size: getProtocolV2ZipEntrySizes(entry).uncompressedSize,
52491
+ sha256: '',
52492
+ },
52493
+ ];
52494
+ });
52466
52495
  }
52467
- const manifest = parseProtocolV2ResourceManifest(manifestValue);
52468
- const selectedFiles = selectProtocolV2ResourceManifestFiles({
52469
- manifest,
52470
- targetsToUpdate: (_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : [],
52471
- });
52472
- const expectedEntryNames = new Set([
52473
- 'manifest.json',
52474
- ...selectedFiles.map(file => file.archive_path),
52475
- ]);
52476
- if (entries.length !== expectedEntryNames.size ||
52477
- entries.some(entry => !expectedEntryNames.has(entry.name))) {
52478
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP contains an unexpected entry', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52496
+ if (selectedFiles.length === 0 || selectedFiles.length > PROTOCOL_V2_RESOURCE_FILE_MAX_COUNT) {
52497
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 local resource ZIP has no resource packages', { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52479
52498
  }
52480
52499
  let totalSize = 0;
52481
- const materializedEntries = [
52482
- { entryName: 'manifest.json', binary: manifestBinary },
52483
- ];
52500
+ const materializedEntries = [];
52501
+ const normalizedFiles = [];
52484
52502
  for (const file of selectedFiles) {
52485
- const entry = zip.file(file.archive_path);
52503
+ const entry = manifestEntry
52504
+ ? zip.file(`${manifestDirectory}${file.archive_path}`)
52505
+ : entries.find(candidate => getProtocolV2LocalResourceArchivePath(candidate.name) === file.archive_path);
52486
52506
  if (!entry) {
52487
52507
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource ZIP is missing ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' });
52488
52508
  }
@@ -52493,11 +52513,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52493
52513
  }
52494
52514
  const fileBinary = yield entry.async('arraybuffer');
52495
52515
  const digest = bytesToHex(sha256.sha256(new Uint8Array(fileBinary)));
52496
- if (fileBinary.byteLength !== file.size || digest !== file.sha256.toLowerCase()) {
52516
+ if (fileBinary.byteLength !== file.size ||
52517
+ (file.sha256 && digest !== file.sha256.toLowerCase())) {
52497
52518
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Protocol V2 local resource file does not match manifest: ${file.archive_path}`, { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52498
52519
  }
52520
+ normalizedFiles.push(Object.assign(Object.assign({}, file), { sha256: digest }));
52499
52521
  materializedEntries.push({ entryName: file.archive_path, binary: fileBinary });
52500
52522
  }
52523
+ manifestBinary !== null && manifestBinary !== void 0 ? manifestBinary : (manifestBinary = new TextEncoder().encode(JSON.stringify({ files: normalizedFiles })).buffer);
52524
+ materializedEntries.unshift({ entryName: 'manifest.json', binary: manifestBinary });
52501
52525
  return { binary, materializedEntries };
52502
52526
  });
52503
52527
  }
@@ -52602,16 +52626,20 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52602
52626
  return sources;
52603
52627
  });
52604
52628
  }
52605
- runProtocolV2PreparedArtifacts(features, firmwareType) {
52629
+ runProtocolV2PreparedArtifacts(features, firmwareType, announceDownload = true) {
52606
52630
  return __awaiter(this, void 0, void 0, function* () {
52607
52631
  try {
52608
- this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
52632
+ if (announceDownload) {
52633
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
52634
+ }
52609
52635
  const installSources = yield this.prepareProtocolV2InstallSources(firmwareType, features);
52610
52636
  const resourceSources = yield this.prepareProtocolV2ResourceSources();
52611
52637
  if (installSources.length === 0 && resourceSources.length === 0) {
52612
52638
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
52613
52639
  }
52614
- this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
52640
+ if (announceDownload) {
52641
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
52642
+ }
52615
52643
  return yield this.executeProtocolV2SourceUpdate({
52616
52644
  installSources,
52617
52645
  resourceSources,
@@ -52897,6 +52925,30 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52897
52925
  return Object.assign(Object.assign({}, target), { binary });
52898
52926
  });
52899
52927
  }
52928
+ downloadRemoteProtocolV2ResourceArchive(features) {
52929
+ return __awaiter(this, void 0, void 0, function* () {
52930
+ const deviceType = getDeviceType(features);
52931
+ if (deviceType !== hdShared.EDeviceType.Pro2 && deviceType !== hdShared.EDeviceType.Neo) {
52932
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive requires a Pro2 or Neo device');
52933
+ }
52934
+ const source = DataManager.getProtocolV2ResourceSource(deviceType);
52935
+ const expectedSha256 = normalizeProtocolV2Hex(source === null || source === void 0 ? void 0 : source.archiveSha256);
52936
+ if (!(source === null || source === void 0 ? void 0 : source.archiveUrl) ||
52937
+ !Number.isSafeInteger(source.archiveSize) ||
52938
+ source.archiveSize <= 0 ||
52939
+ source.archiveSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES ||
52940
+ !expectedSha256 ||
52941
+ !/^[0-9a-f]{64}$/u.test(expectedSha256)) {
52942
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive integrity metadata is invalid', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
52943
+ }
52944
+ const { binary } = yield getSysResourceBinary(source.archiveUrl);
52945
+ if (binary.byteLength !== source.archiveSize ||
52946
+ bytesToHex(sha256.sha256(new Uint8Array(binary))) !== expectedSha256) {
52947
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive does not match the remote config', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52948
+ }
52949
+ return binary;
52950
+ });
52951
+ }
52900
52952
  prepareRemoteProtocolV2Binaries(firmwareType, features, explicitInstallItems = []) {
52901
52953
  var _a, _b;
52902
52954
  return __awaiter(this, void 0, void 0, function* () {
@@ -53056,19 +53108,8 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53056
53108
  }
53057
53109
  return ((_a = this.device.features) === null || _a === void 0 ? void 0 : _a.mode) === 'romloader';
53058
53110
  }
53059
- enterProtocolV2BootloaderMode() {
53111
+ rebootProtocolV2ToBootloader() {
53060
53112
  return __awaiter(this, void 0, void 0, function* () {
53061
- if (this.isProtocolV2RomloaderMode()) {
53062
- Log$6.debug('Protocol V2 device is in romloader mode; start firmware update directly');
53063
- this.protocolV2ExecutionInLoader = true;
53064
- return false;
53065
- }
53066
- if (this.isProtocolV2BootloaderMode()) {
53067
- Log$6.debug('Protocol V2 device is already in bootloader mode, skip reboot');
53068
- this.protocolV2ExecutionInLoader = true;
53069
- this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
53070
- return false;
53071
- }
53072
53113
  try {
53073
53114
  this.postTipMessage(exports.FirmwareUpdateTipMessage.AutoRebootToBootloader);
53074
53115
  yield this.protocolV2Reboot(hdTransport.DeviceRebootType.Bootloader);
@@ -53087,6 +53128,22 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53087
53128
  }
53088
53129
  });
53089
53130
  }
53131
+ enterProtocolV2BootloaderMode() {
53132
+ return __awaiter(this, void 0, void 0, function* () {
53133
+ if (this.isProtocolV2RomloaderMode()) {
53134
+ Log$6.debug('Protocol V2 device is in romloader mode; start firmware update directly');
53135
+ this.protocolV2ExecutionInLoader = true;
53136
+ return false;
53137
+ }
53138
+ if (this.isProtocolV2BootloaderMode()) {
53139
+ Log$6.debug('Protocol V2 device is already in bootloader mode, skip reboot');
53140
+ this.protocolV2ExecutionInLoader = true;
53141
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
53142
+ return false;
53143
+ }
53144
+ return this.rebootProtocolV2ToBootloader();
53145
+ });
53146
+ }
53090
53147
  waitForProtocolV2BootloaderMode(timeout = PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT, retryInterval = 1000) {
53091
53148
  return __awaiter(this, void 0, void 0, function* () {
53092
53149
  const startTime = Date.now();
@@ -53140,81 +53197,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53140
53197
  push(this.params.se04Binary, 'se04.bin', ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04);
53141
53198
  return entries;
53142
53199
  }
53143
- buildProtocolV2ExecutionPhases({ installSources, resourceSources, }) {
53144
- const phases = [];
53145
- const bootResourceSources = resourceSources.filter(source => isProtocolV2BootResourcePackagePath(source.devicePath));
53146
- const remainingResourceSources = resourceSources.filter(source => !isProtocolV2BootResourcePackagePath(source.devicePath));
53147
- if (bootResourceSources.length > 0) {
53148
- phases.push({
53149
- kind: 'resource-sync',
53150
- installSources: [],
53151
- resourceSources: bootResourceSources,
53152
- });
53153
- }
53154
- const bootloaderSources = installSources.filter(source => source.kind === 'bootloader');
53155
- if (bootloaderSources.length > 0) {
53156
- phases.push({
53157
- kind: 'bootloader-install',
53158
- installSources: bootloaderSources,
53159
- resourceSources: [],
53160
- }, {
53161
- kind: 'bootloader-verify',
53162
- installSources: [],
53163
- resourceSources: [],
53164
- });
53165
- }
53166
- if (remainingResourceSources.length > 0) {
53167
- phases.push({
53168
- kind: 'resource-sync',
53169
- installSources: [],
53170
- resourceSources: remainingResourceSources,
53171
- });
53172
- }
53173
- const componentSources = installSources.filter(source => source.kind !== 'bootloader');
53174
- if (componentSources.length > 0) {
53175
- phases.push({
53176
- kind: 'component-install',
53177
- installSources: componentSources,
53178
- resourceSources: [],
53179
- });
53180
- }
53181
- phases.push({
53182
- kind: 'final-verify',
53183
- installSources: [],
53184
- resourceSources: [],
53185
- });
53186
- return phases;
53187
- }
53188
- executeProtocolV2Phases({ installSources, resourceSources, }) {
53200
+ executeProtocolV2SourceUpdate({ installSources, resourceSources, }) {
53189
53201
  return __awaiter(this, void 0, void 0, function* () {
53190
53202
  this.protocolV2BootResourceStagingSafe = false;
53191
- const phases = this.buildProtocolV2ExecutionPhases({
53192
- installSources,
53193
- resourceSources,
53194
- });
53195
- for (const phase of phases) {
53196
- if (phase.kind === 'final-verify') {
53197
- return this.completeProtocolV2FinalVerification();
53198
- }
53199
- if (phase.kind === 'resource-sync') {
53200
- yield this.enterProtocolV2BootloaderMode();
53201
- if (!phase.resourceSources.some(source => isProtocolV2BootResourcePackagePath(source.devicePath))) {
53202
- yield this.ensureProtocolV2BootResourceStagingIsEmpty();
53203
- }
53204
- yield this.executeProtocolV2TransferPhase(phase);
53205
- }
53206
- else if (phase.kind === 'bootloader-install' || phase.kind === 'component-install') {
53207
- yield this.enterProtocolV2BootloaderMode();
53208
- yield this.ensureProtocolV2BootResourceStagingIsEmpty();
53209
- yield this.executeProtocolV2TransferPhase(phase);
53210
- yield this.exitProtocolV2BootloaderToNormal();
53211
- }
53212
- else if (phase.kind === 'bootloader-verify') {
53213
- yield this.waitForProtocolV2FinalFeatures();
53214
- this.assertExpectedProtocolV2Versions(['boot']);
53215
- }
53203
+ if (installSources.length > 0 || resourceSources.length > 0) {
53204
+ yield this.enterProtocolV2BootloaderMode();
53205
+ yield this.ensureProtocolV2BootResourceStagingIsEmpty();
53206
+ yield this.executeProtocolV2TransferPhase({
53207
+ installSources,
53208
+ resourceSources,
53209
+ });
53216
53210
  }
53217
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 execution has no final verification phase');
53211
+ return this.completeProtocolV2FinalVerification();
53218
53212
  });
53219
53213
  }
53220
53214
  ensureProtocolV2BootResourceStagingIsEmpty() {
@@ -53242,14 +53236,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53242
53236
  this.protocolV2BootResourceStagingSafe = true;
53243
53237
  });
53244
53238
  }
53245
- executeProtocolV2SourceUpdate({ installSources, resourceSources, }) {
53246
- return __awaiter(this, void 0, void 0, function* () {
53247
- return this.executeProtocolV2Phases({
53248
- installSources,
53249
- resourceSources,
53250
- });
53251
- });
53252
- }
53253
53239
  executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, }) {
53254
53240
  return __awaiter(this, void 0, void 0, function* () {
53255
53241
  const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
@@ -53265,7 +53251,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53265
53251
  kind: item.kind,
53266
53252
  });
53267
53253
  })));
53268
- return yield this.executeProtocolV2Phases({
53254
+ return yield this.executeProtocolV2SourceUpdate({
53269
53255
  installSources,
53270
53256
  resourceSources: [],
53271
53257
  });
@@ -53466,6 +53452,37 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53466
53452
  });
53467
53453
  return Array.from(expectedTargetIds).filter(targetId => !reportedTargetIds.has(targetId));
53468
53454
  }
53455
+ getProtocolV2ObservableTargetVersions(features) {
53456
+ const versions = new Map();
53457
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, getDeviceBootloaderVersion(features).join('.'));
53458
+ const applicationVersion = getDeviceFirmwareVersion(features).join('.');
53459
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, applicationVersion);
53460
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, applicationVersion);
53461
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR, getDeviceBLEFirmwareVersion(features).join('.'));
53462
+ const secureElementVersions = [
53463
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01, features.se01Version],
53464
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02, features.se02Version],
53465
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, features.se03Version],
53466
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, features.se04Version],
53467
+ ];
53468
+ secureElementVersions.forEach(([targetId, version]) => {
53469
+ if (version)
53470
+ versions.set(targetId, version);
53471
+ });
53472
+ return versions;
53473
+ }
53474
+ hasProtocolV2InstallVersionChanged(expectedTargetIds) {
53475
+ if (!this.protocolV2LastRuntimeProbeFeatures)
53476
+ return false;
53477
+ const currentVersions = this.getProtocolV2ObservableTargetVersions(this.protocolV2LastRuntimeProbeFeatures);
53478
+ return Array.from(expectedTargetIds).some(targetId => {
53479
+ const previousVersion = this.protocolV2InstallBaselineVersions.get(targetId);
53480
+ const currentVersion = currentVersions.get(targetId);
53481
+ return (previousVersion !== undefined &&
53482
+ currentVersion !== undefined &&
53483
+ previousVersion !== currentVersion);
53484
+ });
53485
+ }
53469
53486
  waitForProtocolV2FirmwareUpdateComplete(targets) {
53470
53487
  var _a, _b;
53471
53488
  return __awaiter(this, void 0, void 0, function* () {
@@ -53478,11 +53495,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53478
53495
  let deviceInfo;
53479
53496
  let missingTargetStatusSince;
53480
53497
  let missingTargetStatusKey;
53498
+ let normalModeWithoutInstallEvidenceSince;
53499
+ let installEvidenceObserved = false;
53481
53500
  const resetMissingTargetStatusGrace = () => {
53482
53501
  missingTargetStatusSince = undefined;
53483
53502
  missingTargetStatusKey = undefined;
53484
53503
  };
53485
53504
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
53505
+ this.throwIfAborted();
53486
53506
  try {
53487
53507
  if (shouldReconnect) {
53488
53508
  yield this.reconnectProtocolV2Device();
@@ -53491,24 +53511,39 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53491
53511
  }
53492
53512
  const currentDeviceInfo = deviceInfo;
53493
53513
  try {
53494
- const statusResponse = yield this.device.getCommands().typedCall('DeviceFirmwareUpdateStatusGet', 'DeviceFirmwareUpdateStatus', {
53514
+ const statusResponse = yield this.device.getCommands().typedCall('DeviceFirmwareUpdateStatusGet', ['DeviceFirmwareUpdateStatus', 'Success'], {
53495
53515
  fields: {
53496
53516
  status: true,
53497
53517
  payload_version: true,
53498
53518
  path: true,
53499
53519
  },
53500
53520
  }, { timeoutMs: PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT });
53521
+ if (statusResponse.type === 'Success') {
53522
+ this.protocolV2FinalStatusVerified = true;
53523
+ this.postProgressMessage(100, 'installingFirmware');
53524
+ return;
53525
+ }
53501
53526
  const statusTargets = ((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : []);
53527
+ if (statusTargets.some(target => {
53528
+ const targetId = normalizeProtocolV2TargetId(target.target_id);
53529
+ return targetId !== undefined && expectedTargetIds.has(targetId);
53530
+ })) {
53531
+ installEvidenceObserved = true;
53532
+ normalModeWithoutInstallEvidenceSince = undefined;
53533
+ }
53502
53534
  if (this.assertProtocolV2TargetStatus(statusTargets, expectedTargetIds, expectedPaths)) {
53503
53535
  this.protocolV2FinalStatusVerified = true;
53504
53536
  return;
53505
53537
  }
53506
- if (statusTargets.length === 0 &&
53507
- currentDeviceInfo &&
53508
- (yield this.probeProtocolV2NormalMode(currentDeviceInfo))) {
53509
- Log$6.log('[FirmwareUpdateV4] empty firmware status after confirmed App reboot; update complete');
53510
- this.postProgressMessage(100, 'installingFirmware');
53511
- return;
53538
+ if (statusTargets.length === 0 && currentDeviceInfo) {
53539
+ const isNormalMode = yield this.probeProtocolV2NormalMode(currentDeviceInfo);
53540
+ if (isNormalMode &&
53541
+ (installEvidenceObserved ||
53542
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds))) {
53543
+ Log$6.log('[FirmwareUpdateV4] empty firmware status after confirmed App reboot; update complete');
53544
+ this.postProgressMessage(100, 'installingFirmware');
53545
+ return;
53546
+ }
53512
53547
  }
53513
53548
  const missingTargetIds = this.getProtocolV2MissingTargetIds(statusTargets, expectedTargetIds);
53514
53549
  if (missingTargetIds.length > 0) {
@@ -53541,12 +53576,27 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53541
53576
  if (!currentDeviceInfo) {
53542
53577
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 device identity is unavailable during install polling');
53543
53578
  }
53544
- if (yield this.probeProtocolV2NormalMode(currentDeviceInfo)) {
53579
+ const isNormalMode = yield this.probeProtocolV2NormalMode(currentDeviceInfo);
53580
+ if (isNormalMode &&
53581
+ (installEvidenceObserved ||
53582
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds))) {
53545
53583
  Log$6.log('[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot');
53546
53584
  this.postProgressMessage(100, 'installingFirmware');
53547
53585
  return;
53548
53586
  }
53549
- lastError = new Error('Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode');
53587
+ if (isNormalMode) {
53588
+ const now = Date.now();
53589
+ normalModeWithoutInstallEvidenceSince !== null && normalModeWithoutInstallEvidenceSince !== void 0 ? normalModeWithoutInstallEvidenceSince : (normalModeWithoutInstallEvidenceSince = now);
53590
+ if (now - normalModeWithoutInstallEvidenceSince >=
53591
+ PROTOCOL_V2_MISSING_TARGET_STATUS_GRACE_TIMEOUT) {
53592
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareError, 'Protocol V2 device returned to normal mode without install ACK, target status, or version change');
53593
+ }
53594
+ lastError = new Error('Protocol V2 device is in normal mode but installation is not yet confirmed');
53595
+ }
53596
+ else {
53597
+ normalModeWithoutInstallEvidenceSince = undefined;
53598
+ lastError = new Error('Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode');
53599
+ }
53550
53600
  }
53551
53601
  else {
53552
53602
  shouldReconnect = true;
@@ -53598,6 +53648,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53598
53648
  probeProtocolV2NormalMode(deviceInfo) {
53599
53649
  return __awaiter(this, void 0, void 0, function* () {
53600
53650
  const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
53651
+ this.protocolV2LastRuntimeProbeFeatures = features;
53601
53652
  return features.mode === 'normal' && !features.bootloaderMode;
53602
53653
  });
53603
53654
  }
@@ -53776,11 +53827,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53776
53827
  }
53777
53828
  protocolV2StartFirmwareUpdate({ targets, }) {
53778
53829
  return __awaiter(this, void 0, void 0, function* () {
53830
+ this.protocolV2LastRuntimeProbeFeatures = undefined;
53779
53831
  const commands = this.device.getCommands();
53780
- const response = yield commands.typedCall('DeviceFirmwareUpdateRequest', 'Success', { targets }, { timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT });
53832
+ yield commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
53833
+ yield commands.call('DeviceFirmwareUpdateRequest', {}, { returnAfterWrite: true });
53781
53834
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdating);
53782
53835
  this.postProgressMessage(0, 'installingFirmware');
53783
- return response;
53784
53836
  });
53785
53837
  }
53786
53838
  protocolV2Reboot(rebootType) {
@@ -53913,6 +53965,61 @@ class DeviceGetOnboardingStatus extends BaseMethod {
53913
53965
  }
53914
53966
  }
53915
53967
 
53968
+ const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
53969
+ const JPEG_CONTAINER_OVERHEAD_BYTES = 64 * 1024;
53970
+ const JPEG_MAX_MEMORY_USAGE_IN_MB = 32;
53971
+ const JPEG_MAX_RESOLUTION_IN_MP = 1;
53972
+ function decodeCanonicalBase64({ value, parameterName, maxBytes, }) {
53973
+ if (typeof value !== 'string' || value.length === 0) {
53974
+ throw invalidParameter$1(`Parameter [${parameterName}] must be a non-empty Base64 string.`);
53975
+ }
53976
+ if (value.length > Math.ceil(maxBytes / 3) * 4) {
53977
+ throw invalidParameter$1(`Parameter [${parameterName}] exceeds the maximum supported size.`);
53978
+ }
53979
+ if (value.length % 4 !== 0 || !BASE64_PATTERN.test(value)) {
53980
+ throw invalidParameter$1(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
53981
+ }
53982
+ const decoded = buffer.Buffer.from(value, 'base64');
53983
+ if (decoded.byteLength === 0 || decoded.byteLength > maxBytes) {
53984
+ throw invalidParameter$1(`Parameter [${parameterName}] exceeds the maximum supported size.`);
53985
+ }
53986
+ if (decoded.toString('base64') !== value) {
53987
+ throw invalidParameter$1(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
53988
+ }
53989
+ return Uint8Array.from(decoded);
53990
+ }
53991
+ function decodeJpegBase64ToRgba({ jpegBase64, parameterName, expectedWidth, expectedHeight, }) {
53992
+ const jpegBytes = decodeCanonicalBase64({
53993
+ value: jpegBase64,
53994
+ parameterName,
53995
+ maxBytes: expectedWidth * expectedHeight * 8 + JPEG_CONTAINER_OVERHEAD_BYTES,
53996
+ });
53997
+ if (jpegBytes[0] !== 0xff || jpegBytes[1] !== 0xd8) {
53998
+ throw invalidParameter$1(`Parameter [${parameterName}] must contain a JPEG image.`);
53999
+ }
54000
+ let decoded;
54001
+ try {
54002
+ decoded = jpegJs.decode(jpegBytes, {
54003
+ useTArray: true,
54004
+ formatAsRGBA: true,
54005
+ tolerantDecoding: false,
54006
+ maxResolutionInMP: JPEG_MAX_RESOLUTION_IN_MP,
54007
+ maxMemoryUsageInMB: JPEG_MAX_MEMORY_USAGE_IN_MB,
54008
+ });
54009
+ }
54010
+ catch (_a) {
54011
+ throw invalidParameter$1(`Parameter [${parameterName}] must contain a valid JPEG image.`);
54012
+ }
54013
+ if (decoded.width !== expectedWidth || decoded.height !== expectedHeight) {
54014
+ throw invalidParameter$1(`Parameter [${parameterName}] must contain a ${expectedWidth}x${expectedHeight} JPEG image.`);
54015
+ }
54016
+ const expectedLength = expectedWidth * expectedHeight * 4;
54017
+ if (decoded.data.byteLength !== expectedLength) {
54018
+ throw invalidParameter$1(`Decoded parameter [${parameterName}] must contain ${expectedLength} RGBA bytes.`);
54019
+ }
54020
+ return decoded;
54021
+ }
54022
+
53916
54023
  const Log$4 = getLogger(exports.LoggerNames.Core);
53917
54024
  const MIN_FILE_CHUNK_SIZE = 64;
53918
54025
  const FILE_TRANSFER_RATE_WINDOW_MS = 1000;
@@ -54189,6 +54296,9 @@ function writeProtocolV2File(options) {
54189
54296
 
54190
54297
  const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
54191
54298
  const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
54299
+ const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
54300
+ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2 = 60805;
54301
+ const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
54192
54302
  function normalizeFileName(fileName, data) {
54193
54303
  if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
54194
54304
  throw invalidParameter$1('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
@@ -54207,26 +54317,40 @@ class DeviceUploadWallpaper extends BaseMethod {
54207
54317
  return ['V2'];
54208
54318
  }
54209
54319
  init() {
54210
- const { width, height, rgba, fileName, chunkSize } = this.payload;
54211
- if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
54212
- throw invalidParameter$1(`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`);
54213
- }
54214
- if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
54215
- throw invalidParameter$1('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
54216
- }
54320
+ const { jpegBase64, fileName, chunkSize } = this.payload;
54217
54321
  if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
54218
54322
  throw invalidParameter$1('Parameter [chunkSize] must be a positive integer.');
54219
54323
  }
54220
- const rgbaBytes = rgba instanceof ArrayBuffer
54221
- ? rgba
54222
- : new Uint8Array(rgba.buffer, rgba.byteOffset, rgba.byteLength);
54223
- this.encoded = encodePro2Wallpaper({ width, height, rgba: rgbaBytes });
54324
+ const decoded = decodeJpegBase64ToRgba({
54325
+ jpegBase64,
54326
+ parameterName: 'jpegBase64',
54327
+ expectedWidth: PRO2_WALLPAPER_WIDTH,
54328
+ expectedHeight: PRO2_WALLPAPER_HEIGHT,
54329
+ });
54330
+ this.encoded = encodePro2Wallpaper({
54331
+ width: PRO2_WALLPAPER_WIDTH,
54332
+ height: PRO2_WALLPAPER_HEIGHT,
54333
+ rgba: decoded.data,
54334
+ });
54224
54335
  this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
54225
- this.params = { width, height, rgba: rgbaBytes, fileName, chunkSize };
54336
+ this.params = { jpegBase64, fileName, chunkSize };
54226
54337
  this.unlockPolicy = 'none';
54227
54338
  this.skipForceUpdateCheck = true;
54228
54339
  this.useDevicePassphraseState = false;
54229
54340
  }
54341
+ assertCapabilities() {
54342
+ return __awaiter(this, void 0, void 0, function* () {
54343
+ const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
54344
+ const requiredMessageTypes = [
54345
+ DEVICE_SETTINGS_SET_MESSAGE_TYPE,
54346
+ FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2,
54347
+ FILESYSTEM_DIR_MAKE_MESSAGE_TYPE,
54348
+ ];
54349
+ if (requiredMessageTypes.some(messageType => !supportsProtocolV2Message(protocolInfo, messageType))) {
54350
+ throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
54351
+ }
54352
+ });
54353
+ }
54230
54354
  ensureDirectory() {
54231
54355
  return __awaiter(this, void 0, void 0, function* () {
54232
54356
  if (this.directoryReady)
@@ -54276,6 +54400,7 @@ class DeviceUploadWallpaper extends BaseMethod {
54276
54400
  const { encoded } = this;
54277
54401
  if (!encoded)
54278
54402
  throw invalidParameter$1('Wallpaper data has not been initialized.');
54403
+ yield this.assertCapabilities();
54279
54404
  yield this.ensureDirectory();
54280
54405
  yield this.upload();
54281
54406
  const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
@@ -54300,7 +54425,7 @@ class DeviceUploadNft extends BaseMethod {
54300
54425
  return ['V2'];
54301
54426
  }
54302
54427
  init() {
54303
- const { image, thumbnail, title, subtitle, timestampMs = Date.now(), chunkSize = PRO2_NFT_DEFAULT_CHUNK_SIZE, paceMs = PRO2_NFT_DEFAULT_PACE_MS, timeoutMs = PRO2_NFT_DEFAULT_TIMEOUT_MS, } = this.payload;
54428
+ const { imageJpegBase64, thumbnailJpegBase64, title, subtitle, timestampMs = Date.now(), chunkSize = PRO2_NFT_DEFAULT_CHUNK_SIZE, paceMs = PRO2_NFT_DEFAULT_PACE_MS, timeoutMs = PRO2_NFT_DEFAULT_TIMEOUT_MS, } = this.payload;
54304
54429
  if (!Number.isInteger(chunkSize) ||
54305
54430
  chunkSize < PRO2_NFT_MIN_CHUNK_SIZE ||
54306
54431
  chunkSize > PRO2_NFT_MAX_CHUNK_SIZE) {
@@ -54312,8 +54437,51 @@ class DeviceUploadNft extends BaseMethod {
54312
54437
  if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
54313
54438
  throw invalidParameter$1('Parameter [timeoutMs] must be a positive integer.');
54314
54439
  }
54315
- this.bundle = buildPro2NftBundle({ image, thumbnail, title, subtitle, timestampMs });
54316
- this.params = { image, thumbnail, title, subtitle, timestampMs, chunkSize, paceMs, timeoutMs };
54440
+ const encodedImage = (() => {
54441
+ const decoded = decodeJpegBase64ToRgba({
54442
+ jpegBase64: imageJpegBase64,
54443
+ parameterName: 'imageJpegBase64',
54444
+ expectedWidth: PRO2_NFT_IMAGE_WIDTH,
54445
+ expectedHeight: PRO2_NFT_IMAGE_HEIGHT,
54446
+ });
54447
+ return encodePro2Image({
54448
+ width: PRO2_NFT_IMAGE_WIDTH,
54449
+ height: PRO2_NFT_IMAGE_HEIGHT,
54450
+ rgba: decoded.data,
54451
+ alphaMode: 'black-background',
54452
+ }).data;
54453
+ })();
54454
+ const encodedThumbnail = (() => {
54455
+ const decoded = decodeJpegBase64ToRgba({
54456
+ jpegBase64: thumbnailJpegBase64,
54457
+ parameterName: 'thumbnailJpegBase64',
54458
+ expectedWidth: PRO2_NFT_THUMBNAIL_WIDTH,
54459
+ expectedHeight: PRO2_NFT_THUMBNAIL_HEIGHT,
54460
+ });
54461
+ return encodePro2Image({
54462
+ width: PRO2_NFT_THUMBNAIL_WIDTH,
54463
+ height: PRO2_NFT_THUMBNAIL_HEIGHT,
54464
+ rgba: decoded.data,
54465
+ alphaMode: 'black-background',
54466
+ }).data;
54467
+ })();
54468
+ this.bundle = buildPro2NftBundleFromEncodedImages({
54469
+ image: encodedImage,
54470
+ thumbnail: encodedThumbnail,
54471
+ title,
54472
+ subtitle,
54473
+ timestampMs,
54474
+ });
54475
+ this.params = {
54476
+ imageJpegBase64,
54477
+ thumbnailJpegBase64,
54478
+ title,
54479
+ subtitle,
54480
+ timestampMs,
54481
+ chunkSize,
54482
+ paceMs,
54483
+ timeoutMs,
54484
+ };
54317
54485
  this.unlockPolicy = 'none';
54318
54486
  this.skipForceUpdateCheck = true;
54319
54487
  this.useDevicePassphraseState = false;
@@ -54456,11 +54624,17 @@ class FileWrite extends BaseMethod {
54456
54624
 
54457
54625
  const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
54458
54626
  const PORTFOLIO_CHUNK_SIZE = 2048;
54627
+ const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
54459
54628
  const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
54460
54629
  const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
54461
54630
  class UploadPortfolio extends FileWrite {
54462
54631
  init() {
54463
- const { packageBytes, timeoutMs } = this.payload;
54632
+ const { packageBase64, timeoutMs } = this.payload;
54633
+ const packageBytes = decodeCanonicalBase64({
54634
+ value: packageBase64,
54635
+ parameterName: 'packageBase64',
54636
+ maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
54637
+ });
54464
54638
  this.payload = Object.assign(Object.assign({}, this.payload), { path: PORTFOLIO_PENDING_PATH, offset: 0, data: packageBytes, chunkSize: PORTFOLIO_CHUNK_SIZE, overwrite: true, append: false, emitProgress: false, timeoutMs });
54465
54639
  super.init();
54466
54640
  this.unlockPolicy = 'none';
@@ -63233,8 +63407,9 @@ class TonSignMessage extends BaseMethod {
63233
63407
  if (!request.init_data_length) {
63234
63408
  const deviceType = this.device.getCurrentDeviceType();
63235
63409
  const hasClassic = DeviceModelToTypes.model_classic1s.includes(deviceType);
63236
- const hasSigningMessageRepr = request.signning_message == null;
63237
- return Promise.resolve(Object.assign(Object.assign({}, request), { skip_validate: hasClassic || hasSigningMessageRepr }));
63410
+ const signingMessage = request.signning_message;
63411
+ const shouldSkipValidation = signingMessage == null;
63412
+ return Promise.resolve(Object.assign(Object.assign({}, request), { signing_message: signingMessage, skip_validate: hasClassic || shouldSkipValidation }));
63238
63413
  }
63239
63414
  const [first, rest] = cutString(data, request.init_data_length * 2);
63240
63415
  const response = yield this.device.commands.typedCall('TonTxAck', 'TonSignedMessage', {
@@ -64785,6 +64960,7 @@ const toError = (error) => {
64785
64960
  return new Error(String(error));
64786
64961
  }
64787
64962
  };
64963
+ const isExpectedCompatibilityError = (error) => error instanceof hdShared.HardwareError && error.errorCode === hdShared.HardwareErrorCode.DeviceNotSupportMethod;
64788
64964
  const updateMethodRequestContext = (method, updates) => {
64789
64965
  if (method.requestContext) {
64790
64966
  updateRequestContext(method.requestContext.responseID, updates);
@@ -65158,7 +65334,9 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65158
65334
  return yield task.callPromise.promise;
65159
65335
  }
65160
65336
  catch (e) {
65161
- Log.debug('Device Run Error: ', e);
65337
+ if (!isExpectedCompatibilityError(e)) {
65338
+ Log.debug('Device Run Error: ', e);
65339
+ }
65162
65340
  completeMethodRequestContext(method, e);
65163
65341
  return createResponseMessage(method.responseID, false, { error: e });
65164
65342
  }
@@ -65587,7 +65765,6 @@ const cleanup = () => {
65587
65765
  const pendingUiPromises = _uiPromises;
65588
65766
  _uiPromises = [];
65589
65767
  rejectUiPromises(pendingUiPromises, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, 'UI request was cancelled'));
65590
- Log.debug('Cleanup...');
65591
65768
  };
65592
65769
  const removeDeviceListener = (device) => {
65593
65770
  device.removeAllListeners();