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

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 (57) 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__/deviceSettings.test.ts +0 -1
  6. package/__tests__/deviceUploadNft.test.ts +33 -4
  7. package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +178 -0
  8. package/__tests__/get-device-state.test.ts +52 -13
  9. package/__tests__/logBlockEvent.test.ts +13 -1
  10. package/__tests__/protocol-v2.test.ts +762 -124
  11. package/__tests__/refresh-device-state.test.ts +3 -1
  12. package/__tests__/resourceBase64Boundary.test.ts +48 -0
  13. package/__tests__/ton-sign-message.test.ts +84 -0
  14. package/dist/api/FirmwareUpdateV4.d.ts +10 -3
  15. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  16. package/dist/api/UploadPortfolio.d.ts +1 -1
  17. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  18. package/dist/api/helpers/base64Data.d.ts +16 -0
  19. package/dist/api/helpers/base64Data.d.ts.map +1 -0
  20. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +2 -3
  21. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
  22. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +2 -3
  23. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  24. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  25. package/dist/core/index.d.ts.map +1 -1
  26. package/dist/device/Device.d.ts +7 -2
  27. package/dist/device/Device.d.ts.map +1 -1
  28. package/dist/device/DeviceCommands.d.ts.map +1 -1
  29. package/dist/device/DevicePool.d.ts.map +1 -1
  30. package/dist/events/logBlockEvent.d.ts.map +1 -1
  31. package/dist/index.d.ts +11 -14
  32. package/dist/index.js +455 -200
  33. package/dist/protocols/protocol-v2/features.d.ts +9 -1
  34. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  35. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  36. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  37. package/dist/types/api/protocolV2.d.ts +1 -1
  38. package/dist/types/api/protocolV2.d.ts.map +1 -1
  39. package/dist/utils/pro2Nft.d.ts +7 -0
  40. package/dist/utils/pro2Nft.d.ts.map +1 -1
  41. package/package.json +6 -4
  42. package/src/api/FirmwareUpdateV4.ts +326 -174
  43. package/src/api/UploadPortfolio.ts +9 -2
  44. package/src/api/helpers/base64Data.ts +85 -0
  45. package/src/api/protocol-v2/DeviceUploadNft.ts +56 -8
  46. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +37 -18
  47. package/src/api/ton/TonSignMessage.ts +5 -3
  48. package/src/core/index.ts +6 -2
  49. package/src/device/Device.ts +53 -31
  50. package/src/device/DeviceCommands.ts +4 -14
  51. package/src/device/DevicePool.ts +6 -2
  52. package/src/events/logBlockEvent.ts +14 -1
  53. package/src/protocols/protocol-v2/features.ts +19 -2
  54. package/src/protocols/protocol-v2/index.ts +2 -0
  55. package/src/types/api/protocolV2.ts +1 -1
  56. package/src/utils/deviceSettings.ts +1 -1
  57. 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
 
@@ -41474,6 +41475,11 @@ const LogLabelMethod = new Set([
41474
41475
  'fileWrite',
41475
41476
  'fileRead',
41476
41477
  ]);
41478
+ const LogPayloadBlockMethod = new Set([
41479
+ 'deviceUploadNft',
41480
+ 'deviceUploadWallpaper',
41481
+ 'uploadPortfolio',
41482
+ ]);
41477
41483
  const SensitiveLogKeys = new Set([
41478
41484
  'devicestate',
41479
41485
  'entropy',
@@ -41530,7 +41536,10 @@ function getLogBlockLabel(message) {
41530
41536
  return undefined;
41531
41537
  }
41532
41538
  function getSafeLogPayload(value, blockLabel) {
41533
- if (blockLabel && (LogBlockEvent.has(blockLabel) || isSigningMethod(blockLabel))) {
41539
+ if (blockLabel &&
41540
+ (LogBlockEvent.has(blockLabel) ||
41541
+ LogPayloadBlockMethod.has(blockLabel) ||
41542
+ isSigningMethod(blockLabel))) {
41534
41543
  return { method: blockLabel, payload: '[REDACTED]' };
41535
41544
  }
41536
41545
  const redactedValue = redactLogValue(value, new WeakSet());
@@ -42464,7 +42473,7 @@ const getAutoShutDownOptions = (deviceType, protocol) => {
42464
42473
  return withNever([60000, 120000, 300000, 600000], protocol);
42465
42474
  case hdShared.EDeviceType.Pro2:
42466
42475
  case hdShared.EDeviceType.Neo:
42467
- return withNever([60000, 120000, 300000, 600000, 1800000], protocol);
42476
+ return withNever([60000, 120000, 300000, 600000], protocol);
42468
42477
  default:
42469
42478
  return [];
42470
42479
  }
@@ -42723,18 +42732,14 @@ function getCompletePro2NftBasenames(childFiles) {
42723
42732
  function utf8Length(value) {
42724
42733
  return new TextEncoder().encode(value).byteLength;
42725
42734
  }
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}.`);
42735
+ function buildPro2NftBundleFromEncodedImages(options) {
42736
+ const { image, thumbnail, title, subtitle, timestampMs } = options;
42737
+ if (!(image instanceof Uint8Array) || image.byteLength === 0) {
42738
+ throw invalidParameter$1('Parameter [image] must contain encoded NFT image data.');
42729
42739
  }
42730
- if (!(image.rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(image.rgba)) {
42731
- throw invalidParameter$1(`Parameter [${name}.rgba] must be an ArrayBuffer or Uint8Array.`);
42740
+ if (!(thumbnail instanceof Uint8Array) || thumbnail.byteLength === 0) {
42741
+ throw invalidParameter$1('Parameter [thumbnail] must contain encoded NFT thumbnail data.');
42732
42742
  }
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
42743
  const titleLength = typeof title === 'string' ? utf8Length(title) : 0;
42739
42744
  const subtitleLength = typeof subtitle === 'string' ? utf8Length(subtitle) : Number.POSITIVE_INFINITY;
42740
42745
  if (titleLength < 1 || titleLength > 63) {
@@ -42746,17 +42751,15 @@ function buildPro2NftBundle(options) {
42746
42751
  if (!Number.isSafeInteger(timestampMs) || timestampMs <= 0) {
42747
42752
  throw invalidParameter$1('Parameter [timestampMs] must be a positive safe integer.');
42748
42753
  }
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
42754
  const metadata = new TextEncoder().encode(JSON.stringify({ title, subtitle }));
42752
42755
  if (metadata.byteLength === 0 || metadata.byteLength > 512) {
42753
42756
  throw invalidParameter$1('Pro2 NFT metadata must contain 1 to 512 UTF-8 bytes.');
42754
42757
  }
42755
- const hash8 = utils.bytesToHex(blake2s.blake2s(encodedImage)).slice(0, 8);
42758
+ const hash8 = utils.bytesToHex(blake2s.blake2s(image)).slice(0, 8);
42756
42759
  return {
42757
42760
  basename: `nft-${hash8}-${timestampMs}`,
42758
- image: encodedImage,
42759
- thumbnail: encodedThumbnail,
42761
+ image,
42762
+ thumbnail,
42760
42763
  metadata,
42761
42764
  };
42762
42765
  }
@@ -43276,9 +43279,13 @@ class DevicePool extends events.exports {
43276
43279
  }
43277
43280
  static _refreshProtocolV2DiscoveryState(device) {
43278
43281
  return __awaiter(this, void 0, void 0, function* () {
43279
- yield device.getDeviceState({ refreshSections: ['status'] });
43282
+ yield device.getDeviceState({
43283
+ refreshSections: ['status'],
43284
+ });
43280
43285
  try {
43281
- yield device.getDeviceState({ refreshSections: ['settings'] });
43286
+ yield device.getDeviceState({
43287
+ refreshSections: ['settings'],
43288
+ });
43282
43289
  }
43283
43290
  catch (error) {
43284
43291
  Log$j.debug('Unable to refresh Protocol V2 device label during discovery', error);
@@ -43720,9 +43727,6 @@ class DeviceCommands {
43720
43727
  const promise = this.transport.call(this.mainId, type, msg !== null && msg !== void 0 ? msg : {}, options);
43721
43728
  this.callPromise = promise;
43722
43729
  const res = yield promise;
43723
- if (!shouldReduceDebug) {
43724
- LogCore.debug('[DeviceCommands] [call] Received', res.type, hdTransport.getSafeTransportLogPayload(res.message, res.type));
43725
- }
43726
43730
  return res;
43727
43731
  }
43728
43732
  catch (error) {
@@ -43815,12 +43819,10 @@ class DeviceCommands {
43815
43819
  if (!shouldReduceDebugForCall(callType)) {
43816
43820
  Log$h.debug('_filterCommonTypes: ', {
43817
43821
  request: callType,
43818
- response: callType === 'DeviceFirmwareUpdateStatusGet'
43819
- ? {
43820
- type: res.type,
43821
- message: hdTransport.getSafeTransportLogPayload(res.message, res.type),
43822
- }
43823
- : res.type,
43822
+ response: {
43823
+ type: res.type,
43824
+ message: hdTransport.getSafeTransportLogPayload(res.message, res.type),
43825
+ },
43824
43826
  });
43825
43827
  }
43826
43828
  }
@@ -44226,6 +44228,7 @@ const getProtocolV2SeState = (se) => {
44226
44228
  }
44227
44229
  };
44228
44230
  const getProtocolV2SeType = (se) => normalizeEnumValue(hdTransport.DeviceSeType, se === null || se === void 0 ? void 0 : se.type);
44231
+ const isLegacyProtocolV2ProtocolInfo = (protocolInfo) => Object.prototype.hasOwnProperty.call(protocolInfo, 'protobuf_definition');
44229
44232
  const parseProtocolV2BuildFingerprint = (buildFingerprint) => {
44230
44233
  if (!buildFingerprint)
44231
44234
  return null;
@@ -44240,12 +44243,20 @@ const parseProtocolV2BuildFingerprint = (buildFingerprint) => {
44240
44243
  }
44241
44244
  return { binary, version, commit, environment, buildType };
44242
44245
  };
44243
- const getProtocolV2RuntimeMode = (protocolInfo) => {
44244
- var _a;
44246
+ const getProtocolV2RuntimeMode = (protocolInfo, deviceInfo) => {
44247
+ var _a, _b, _c, _d;
44245
44248
  const binary = (_a = parseProtocolV2BuildFingerprint(protocolInfo.build_fingerprint)) === null || _a === void 0 ? void 0 : _a.binary;
44246
44249
  if (binary === 'application')
44247
44250
  return 'normal';
44248
- return binary;
44251
+ if (binary)
44252
+ return binary;
44253
+ if (isLegacyProtocolV2ProtocolInfo(protocolInfo) && !((_b = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.fw) === null || _b === void 0 ? void 0 : _b.application)) {
44254
+ if ((_c = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.fw) === null || _c === void 0 ? void 0 : _c.romloader)
44255
+ return 'romloader';
44256
+ if ((_d = deviceInfo === null || deviceInfo === void 0 ? void 0 : deviceInfo.fw) === null || _d === void 0 ? void 0 : _d.bootloader)
44257
+ return 'bootloader';
44258
+ }
44259
+ return undefined;
44249
44260
  };
44250
44261
  const PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE = 60602;
44251
44262
  const supportsProtocolV2Message = (protocolInfo, messageType) => protocolInfo.supported_messages.includes(messageType);
@@ -45247,6 +45258,7 @@ class Device extends events.exports {
45247
45258
  yield this.commands.dispose(false);
45248
45259
  }
45249
45260
  this.commands = new DeviceCommands(this, (_g = this.mainId) !== null && _g !== void 0 ? _g : '');
45261
+ this.invalidateProtocolV2RuntimeState();
45250
45262
  }
45251
45263
  catch (error) {
45252
45264
  if (options === null || options === void 0 ? void 0 : options.forceProtocolDetection) {
@@ -45641,8 +45653,7 @@ class Device extends events.exports {
45641
45653
  commands: this.commands,
45642
45654
  timeoutMs: options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs,
45643
45655
  });
45644
- const features = yield this.probeProtocolV2RuntimeState(deviceInfo, options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs);
45645
- Log$g.debug('Protocol V2 features:', features);
45656
+ yield this.probeProtocolV2RuntimeState(deviceInfo, options === null || options === void 0 ? void 0 : options.protocolV2DeviceInfoTimeoutMs);
45646
45657
  }
45647
45658
  catch (error) {
45648
45659
  Log$g.error('Protocol V2 initialization failed:', error);
@@ -45664,7 +45675,7 @@ class Device extends events.exports {
45664
45675
  });
45665
45676
  }
45666
45677
  getDeviceState(params = {}) {
45667
- var _a, _b, _c;
45678
+ var _a, _b, _c, _d;
45668
45679
  return __awaiter(this, void 0, void 0, function* () {
45669
45680
  const refresh = new Set((_a = params.refreshSections) !== null && _a !== void 0 ? _a : []);
45670
45681
  const getProtocolV2DeviceInfoRequest = () => {
@@ -45712,9 +45723,12 @@ class Device extends events.exports {
45712
45723
  }
45713
45724
  }
45714
45725
  if (refresh.has('status') && !initializedWithDeviceInfo) {
45715
- yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo);
45726
+ const cachedMode = (_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode;
45727
+ yield this.probeProtocolV2RuntimeState(refreshedDeviceInfo, undefined, {
45728
+ forceRuntimeContextRefresh: cachedMode === 'bootloader' || cachedMode === 'romloader',
45729
+ });
45716
45730
  }
45717
- if (refresh.has('settings') && ((_c = this.state) === null || _c === void 0 ? void 0 : _c.status.mode) === 'normal') {
45731
+ if (refresh.has('settings') && ((_d = this.state) === null || _d === void 0 ? void 0 : _d.status.mode) === 'normal') {
45718
45732
  const { message } = yield this.commands.typedCall('DeviceSettingsGet', 'DeviceSettings', {});
45719
45733
  this.updateState(mapDeviceSettingsToState(message), 'settings-read');
45720
45734
  }
@@ -45751,9 +45765,10 @@ class Device extends events.exports {
45751
45765
  source,
45752
45766
  changedKeys: result.changedKeys,
45753
45767
  };
45754
- Log$g.debug('Device state patch committed', {
45768
+ Log$g.debug('Device state updated', {
45755
45769
  source,
45756
- keys: result.changedKeys,
45770
+ revision: result.revision,
45771
+ changedKeyCount: result.changedKeys.length,
45757
45772
  });
45758
45773
  this.emit(DEVICE.STATE, this, event);
45759
45774
  if (result.state.protocol === 'V1') {
@@ -45772,12 +45787,14 @@ class Device extends events.exports {
45772
45787
  this.updateState(mapFeaturesToState(normalized), source);
45773
45788
  return this.features;
45774
45789
  }
45775
- ensureProtocolV2RuntimeContext(timeoutMs) {
45790
+ ensureProtocolV2RuntimeContext(timeoutMs, options) {
45776
45791
  var _a, _b, _c, _d;
45777
45792
  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);
45793
+ const cachedProtocolInfo = (options === null || options === void 0 ? void 0 : options.forceRefresh) === true
45794
+ ? undefined
45795
+ : (_a = this.protocolV2RuntimeContext) !== null && _a !== void 0 ? _a : (!this.protocolV2StateNeedsReload
45796
+ ? (_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
45797
+ : undefined);
45781
45798
  if (cachedProtocolInfo) {
45782
45799
  this.protocolV2RuntimeContext = cachedProtocolInfo;
45783
45800
  return cachedProtocolInfo;
@@ -45812,12 +45829,15 @@ class Device extends events.exports {
45812
45829
  }
45813
45830
  });
45814
45831
  }
45815
- probeProtocolV2RuntimeState(deviceInfo, timeoutMs) {
45832
+ probeProtocolV2RuntimeState(deviceInfo, timeoutMs, options) {
45816
45833
  var _a, _b, _c;
45817
45834
  return __awaiter(this, void 0, void 0, function* () {
45818
- const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs);
45819
- const runtimeMode = getProtocolV2RuntimeMode(protocolInfo);
45835
+ const protocolInfo = yield this.ensureProtocolV2RuntimeContext(timeoutMs, {
45836
+ forceRefresh: options === null || options === void 0 ? void 0 : options.forceRuntimeContextRefresh,
45837
+ });
45820
45838
  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;
45839
+ const runtimeMode = getProtocolV2RuntimeMode(protocolInfo, runtimeDeviceInfo);
45840
+ const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
45821
45841
  const protocolV2DeviceType = runtimeDeviceInfo
45822
45842
  ? resolveProtocolV2DeviceIdentity((_c = runtimeDeviceInfo.hw) === null || _c === void 0 ? void 0 : _c.Device_type).deviceType
45823
45843
  : this.getCurrentDeviceType();
@@ -45826,7 +45846,8 @@ class Device extends events.exports {
45826
45846
  protocolV2DeviceType !== hdShared.EDeviceType.Neo) {
45827
45847
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceInitializeFailed, 'Protocol V2 romloader mode is only supported for Pro2 and Neo.');
45828
45848
  }
45829
- const deviceStatusSupported = supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
45849
+ const deviceStatusSupported = legacyProtocolInfo ||
45850
+ supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
45830
45851
  if (runtimeMode === 'bootloader' || runtimeMode === 'romloader') {
45831
45852
  return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
45832
45853
  }
@@ -45874,8 +45895,7 @@ class Device extends events.exports {
45874
45895
  const previousStatus = (_d = (_c = this.state) === null || _c === void 0 ? void 0 : _c.raw) === null || _d === void 0 ? void 0 : _d.protocolV2DeviceStatus;
45875
45896
  return this.updateProtocolV2Features(previousDeviceInfo, Object.assign(Object.assign({}, previousStatus), status));
45876
45897
  }
45877
- markTransportDisconnected() {
45878
- this.deviceAcquired = false;
45898
+ invalidateProtocolV2RuntimeState() {
45879
45899
  if (!this.isProtocolV2())
45880
45900
  return;
45881
45901
  this.protocolV2StateNeedsReload = true;
@@ -45884,6 +45904,10 @@ class Device extends events.exports {
45884
45904
  this.protocolV2RuntimeContextRequestToken = undefined;
45885
45905
  this.clearPreInitialized();
45886
45906
  }
45907
+ markTransportDisconnected() {
45908
+ this.deviceAcquired = false;
45909
+ this.invalidateProtocolV2RuntimeState();
45910
+ }
45887
45911
  invalidateAfterWipe() {
45888
45912
  const deviceId = this.getCurrentDeviceId();
45889
45913
  if (deviceId) {
@@ -45893,10 +45917,7 @@ class Device extends events.exports {
45893
45917
  if (this.originalDescriptor.path !== deviceId) {
45894
45918
  deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
45895
45919
  }
45896
- this.protocolV2StateNeedsReload = true;
45897
- this.protocolV2RuntimeContext = undefined;
45898
- this.protocolV2RuntimeContextPromise = undefined;
45899
- this.protocolV2RuntimeContextRequestToken = undefined;
45920
+ this.invalidateProtocolV2RuntimeState();
45900
45921
  }
45901
45922
  this.passphraseState = undefined;
45902
45923
  this.stateStore = new DeviceStateStore();
@@ -45906,11 +45927,7 @@ class Device extends events.exports {
45906
45927
  markProtocolV2Reboot(rebootType) {
45907
45928
  if (!this.isProtocolV2())
45908
45929
  return;
45909
- this.protocolV2StateNeedsReload = true;
45910
- this.protocolV2RuntimeContext = undefined;
45911
- this.protocolV2RuntimeContextPromise = undefined;
45912
- this.protocolV2RuntimeContextRequestToken = undefined;
45913
- this.clearPreInitialized();
45930
+ this.invalidateProtocolV2RuntimeState();
45914
45931
  let loaderMode;
45915
45932
  if (rebootType === hdTransport.DeviceRebootType.Bootloader) {
45916
45933
  loaderMode = 'bootloader';
@@ -45966,6 +45983,7 @@ class Device extends events.exports {
45966
45983
  if (device.features) {
45967
45984
  this._updateFeatures(device.features);
45968
45985
  }
45986
+ this.invalidateProtocolV2RuntimeState();
45969
45987
  }
45970
45988
  run(fn, options) {
45971
45989
  return __awaiter(this, void 0, void 0, function* () {
@@ -51813,12 +51831,36 @@ const isProtocolV2ReconnectProbeError = (error) => {
51813
51831
  return ((message.includes('device protocol mismatch') && message.includes('expected v2')) ||
51814
51832
  message.includes('did not respond to expected protocol'));
51815
51833
  };
51834
+ const PROTOCOL_V2_BLE_INSTALL_INTERRUPTION_ERROR_CODES = new Set([
51835
+ hdShared.HardwareErrorCode.BleConnectedError,
51836
+ hdShared.HardwareErrorCode.BleCharacteristicNotifyError,
51837
+ hdShared.HardwareErrorCode.BleForceCleanRunPromise,
51838
+ hdShared.HardwareErrorCode.BleDeviceDisconnected,
51839
+ ]);
51840
+ const isProtocolV2BleInstallInterruptionError = (error) => {
51841
+ if (error instanceof hdShared.HardwareError &&
51842
+ PROTOCOL_V2_BLE_INSTALL_INTERRUPTION_ERROR_CODES.has(error.errorCode)) {
51843
+ return true;
51844
+ }
51845
+ const message = getProtocolV2UnknownErrorText(error).toLowerCase();
51846
+ const compactMessage = message.replace(/\s+/gu, '');
51847
+ return (/react native ble transport (?:released|disconnected)/u.test(message) ||
51848
+ (compactMessage.includes('rxerrorerror6') &&
51849
+ (compactMessage.includes('multiplatformbleadapter') ||
51850
+ compactMessage.includes('multipalformebleadapter'))));
51851
+ };
51816
51852
  const isProtocolV2FirmwareStatusEndpointUnavailable = (error) => {
51817
51853
  const message = getProtocolV2UnknownErrorText(error).toLowerCase();
51818
51854
  return (message.includes('handler not registered') ||
51819
51855
  message.includes('message handler not found') ||
51820
51856
  message.includes('unsupported message'));
51821
51857
  };
51858
+ const isProtocolV2FirmwareUpdateEndpointUnavailable = (error) => {
51859
+ const message = getProtocolV2UnknownErrorText(error).toLowerCase();
51860
+ return (message.includes('handler not registered') ||
51861
+ message.includes('message handler not found') ||
51862
+ message.includes('unsupported message'));
51863
+ };
51822
51864
  const isProtocolV2TerminalInstallStatusError = (error) => {
51823
51865
  var _a;
51824
51866
  return error instanceof hdShared.HardwareError &&
@@ -51951,9 +51993,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
51951
51993
  this.protocolV2HasExplicitTargetSelection = false;
51952
51994
  this.protocolV2PreparedSources = [];
51953
51995
  this.protocolV2ExecutionInLoader = false;
51996
+ this.protocolV2LegacyDirectUpdate = false;
51954
51997
  this.protocolV2BootResourceStagingSafe = false;
51955
51998
  this.protocolV2CompletedTargetVersions = new Map();
51956
51999
  this.protocolV2FinalStatusVerified = false;
52000
+ this.protocolV2InstallAckReceived = false;
52001
+ this.protocolV2InstallBaselineVersions = new Map();
51957
52002
  }
51958
52003
  getSupportedProtocols() {
51959
52004
  return ['V2'];
@@ -52131,6 +52176,9 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52131
52176
  return __awaiter(this, void 0, void 0, function* () {
52132
52177
  yield this.captureProtocolV2PhysicalIdentity();
52133
52178
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
52179
+ this.protocolV2InstallBaselineVersions =
52180
+ this.getProtocolV2ObservableTargetVersions(deviceFeatures);
52181
+ this.protocolV2LastRuntimeProbeFeatures = undefined;
52134
52182
  const currentDeviceType = this.device.getCurrentDeviceType();
52135
52183
  const capabilityDeviceType = currentDeviceType === hdShared.EDeviceType.Pro2 || currentDeviceType === hdShared.EDeviceType.Neo
52136
52184
  ? currentDeviceType
@@ -52139,9 +52187,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52139
52187
  const deviceFirmwareType = getFirmwareType(deviceFeatures);
52140
52188
  const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
52141
52189
  this.validateExpectedTargetVersions();
52190
+ const wantsResources = !!((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'));
52142
52191
  if (!this.params.preparedPlan &&
52143
52192
  this.params.resourceArchiveBinary &&
52144
- ((_b = this.params.targetsToUpdate) === null || _b === void 0 ? void 0 : _b.includes('resource'))) {
52193
+ ((_c = this.params.targetsToUpdate) === null || _c === void 0 ? void 0 : _c.includes('resource'))) {
52145
52194
  const localMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
52146
52195
  features: deviceFeatures,
52147
52196
  firmwareType,
@@ -52153,14 +52202,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52153
52202
  localMemoryHost.release();
52154
52203
  }
52155
52204
  }
52156
- const hasPreparedComponentArtifacts = Object.values((_c = this.params.componentArtifacts) !== null && _c !== void 0 ? _c : {}).some(Boolean);
52205
+ const hasPreparedComponentArtifacts = Object.values((_d = this.params.componentArtifacts) !== null && _d !== void 0 ? _d : {}).some(Boolean);
52157
52206
  if (this.params.preparedPlan || hasPreparedComponentArtifacts) {
52158
52207
  return this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
52159
52208
  }
52160
- const wantsResources = !!((_d = this.params.targetsToUpdate) === null || _d === void 0 ? void 0 : _d.includes('resource'));
52161
52209
  let fwBinaryMap = [];
52162
52210
  let bootloaderBinary = null;
52163
52211
  let installItems;
52212
+ let resourceMemoryHost;
52164
52213
  try {
52165
52214
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
52166
52215
  fwBinaryMap = this.collectExplicitTargetBinaries();
@@ -52173,20 +52222,19 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52173
52222
  const needsRemoteFirmware = ((_e = this.params.targetsToUpdate) === null || _e === void 0 ? void 0 : _e.length)
52174
52223
  ? missingFirmwareTargets.length > 0
52175
52224
  : 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 &&
52225
+ const needsSdkManagedArtifacts = needsRemoteFirmware || wantsResources;
52226
+ if (needsSdkManagedArtifacts &&
52182
52227
  (this.params.artifactReader ||
52183
52228
  DataManager.getSettings('firmwareManifestMode') === 'external-only')) {
52184
52229
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 firmware artifacts must be prepared by the external firmware host', {
52185
52230
  firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
52186
52231
  });
52187
52232
  }
52188
- if (needsRemoteFirmware) {
52189
- yield DataManager.forceReloadData();
52233
+ if (needsSdkManagedArtifacts) {
52234
+ yield DataManager.forceReloadData({
52235
+ requireResources: wantsResources,
52236
+ resourceDeviceType: capabilityDeviceType === hdShared.EDeviceType.Neo ? hdShared.EDeviceType.Neo : hdShared.EDeviceType.Pro2,
52237
+ });
52190
52238
  }
52191
52239
  if (needsRemoteFirmware) {
52192
52240
  const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures, explicitInstallItems);
@@ -52206,9 +52254,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52206
52254
  targetId: item.targetId,
52207
52255
  }));
52208
52256
  }
52257
+ if (wantsResources) {
52258
+ this.params.resourceArchiveBinary = yield this.downloadRemoteProtocolV2ResourceArchive(deviceFeatures);
52259
+ resourceMemoryHost = yield this.prepareProtocolV2LocalMemoryHost({
52260
+ features: deviceFeatures,
52261
+ firmwareType,
52262
+ availableInstallItems: installItems !== null && installItems !== void 0 ? installItems : explicitInstallItems,
52263
+ });
52264
+ }
52209
52265
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
52210
52266
  }
52211
52267
  catch (err) {
52268
+ resourceMemoryHost === null || resourceMemoryHost === void 0 ? void 0 : resourceMemoryHost.release();
52212
52269
  if (typeof err === 'object' &&
52213
52270
  err !== null &&
52214
52271
  'params' in err &&
@@ -52220,6 +52277,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52220
52277
  }
52221
52278
  throw normalizeFirmwarePreparationError(err);
52222
52279
  }
52280
+ if (resourceMemoryHost) {
52281
+ try {
52282
+ return yield this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType, false);
52283
+ }
52284
+ finally {
52285
+ resourceMemoryHost.release();
52286
+ }
52287
+ }
52223
52288
  if (!bootloaderBinary && fwBinaryMap.length === 0 && !(installItems === null || installItems === void 0 ? void 0 : installItems.length)) {
52224
52289
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
52225
52290
  }
@@ -52319,13 +52384,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52319
52384
  return installSources;
52320
52385
  });
52321
52386
  }
52322
- prepareProtocolV2LocalMemoryHost({ features, firmwareType, }) {
52387
+ prepareProtocolV2LocalMemoryHost({ features, firmwareType, availableInstallItems = this.buildProtocolV2InstallItems({
52388
+ bootloaderBinary: this.prepareBootloaderBinary(),
52389
+ fwBinaryMap: this.collectExplicitTargetBinaries(),
52390
+ }), }) {
52323
52391
  var _a, _b;
52324
52392
  return __awaiter(this, void 0, void 0, function* () {
52325
- const availableInstallItems = this.buildProtocolV2InstallItems({
52326
- bootloaderBinary: this.prepareBootloaderBinary(),
52327
- fwBinaryMap: this.collectExplicitTargetBinaries(),
52328
- });
52329
52393
  const requestedComponentTargets = new Set(((_a = this.params.targetsToUpdate) !== null && _a !== void 0 ? _a : []).filter((target) => target !== 'resource' && target !== 'boot_resources'));
52330
52394
  const localComponentTargets = new Set(availableInstallItems.flatMap(item => {
52331
52395
  const target = PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(item.targetId);
@@ -52602,16 +52666,20 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52602
52666
  return sources;
52603
52667
  });
52604
52668
  }
52605
- runProtocolV2PreparedArtifacts(features, firmwareType) {
52669
+ runProtocolV2PreparedArtifacts(features, firmwareType, announceDownload = true) {
52606
52670
  return __awaiter(this, void 0, void 0, function* () {
52607
52671
  try {
52608
- this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
52672
+ if (announceDownload) {
52673
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
52674
+ }
52609
52675
  const installSources = yield this.prepareProtocolV2InstallSources(firmwareType, features);
52610
52676
  const resourceSources = yield this.prepareProtocolV2ResourceSources();
52611
52677
  if (installSources.length === 0 && resourceSources.length === 0) {
52612
52678
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
52613
52679
  }
52614
- this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
52680
+ if (announceDownload) {
52681
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.FinishDownloadFirmware);
52682
+ }
52615
52683
  return yield this.executeProtocolV2SourceUpdate({
52616
52684
  installSources,
52617
52685
  resourceSources,
@@ -52897,6 +52965,30 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
52897
52965
  return Object.assign(Object.assign({}, target), { binary });
52898
52966
  });
52899
52967
  }
52968
+ downloadRemoteProtocolV2ResourceArchive(features) {
52969
+ return __awaiter(this, void 0, void 0, function* () {
52970
+ const deviceType = getDeviceType(features);
52971
+ if (deviceType !== hdShared.EDeviceType.Pro2 && deviceType !== hdShared.EDeviceType.Neo) {
52972
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive requires a Pro2 or Neo device');
52973
+ }
52974
+ const source = DataManager.getProtocolV2ResourceSource(deviceType);
52975
+ const expectedSha256 = normalizeProtocolV2Hex(source === null || source === void 0 ? void 0 : source.archiveSha256);
52976
+ if (!(source === null || source === void 0 ? void 0 : source.archiveUrl) ||
52977
+ !Number.isSafeInteger(source.archiveSize) ||
52978
+ source.archiveSize <= 0 ||
52979
+ source.archiveSize > PROTOCOL_V2_RESOURCE_TOTAL_MAX_BYTES ||
52980
+ !expectedSha256 ||
52981
+ !/^[0-9a-f]{64}$/u.test(expectedSha256)) {
52982
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive integrity metadata is invalid', { firmwareUpdateCode: 'FirmwarePlanInvalid' });
52983
+ }
52984
+ const { binary } = yield getSysResourceBinary(source.archiveUrl);
52985
+ if (binary.byteLength !== source.archiveSize ||
52986
+ bytesToHex(sha256.sha256(new Uint8Array(binary))) !== expectedSha256) {
52987
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 resource archive does not match the remote config', { firmwareUpdateCode: 'FirmwareArtifactReceiptMismatch' });
52988
+ }
52989
+ return binary;
52990
+ });
52991
+ }
52900
52992
  prepareRemoteProtocolV2Binaries(firmwareType, features, explicitInstallItems = []) {
52901
52993
  var _a, _b;
52902
52994
  return __awaiter(this, void 0, void 0, function* () {
@@ -53056,19 +53148,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53056
53148
  }
53057
53149
  return ((_a = this.device.features) === null || _a === void 0 ? void 0 : _a.mode) === 'romloader';
53058
53150
  }
53059
- enterProtocolV2BootloaderMode() {
53151
+ isLegacyProtocolV2Runtime() {
53152
+ var _a, _b;
53153
+ const protocolInfo = (_b = (_a = this.device.state) === null || _a === void 0 ? void 0 : _a.raw) === null || _b === void 0 ? void 0 : _b.protocolV2ProtocolInfo;
53154
+ return protocolInfo ? isLegacyProtocolV2ProtocolInfo(protocolInfo) : false;
53155
+ }
53156
+ rebootProtocolV2ToBootloader() {
53060
53157
  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
53158
  try {
53073
53159
  this.postTipMessage(exports.FirmwareUpdateTipMessage.AutoRebootToBootloader);
53074
53160
  yield this.protocolV2Reboot(hdTransport.DeviceRebootType.Bootloader);
@@ -53087,6 +53173,25 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53087
53173
  }
53088
53174
  });
53089
53175
  }
53176
+ enterProtocolV2BootloaderMode() {
53177
+ return __awaiter(this, void 0, void 0, function* () {
53178
+ this.protocolV2LegacyDirectUpdate = false;
53179
+ if (this.isProtocolV2RomloaderMode()) {
53180
+ Log$6.debug('Protocol V2 device is in romloader mode; start firmware update directly');
53181
+ this.protocolV2LegacyDirectUpdate = this.isLegacyProtocolV2Runtime();
53182
+ this.protocolV2ExecutionInLoader = true;
53183
+ return false;
53184
+ }
53185
+ if (this.isProtocolV2BootloaderMode()) {
53186
+ Log$6.debug('Protocol V2 device is already in bootloader mode, skip reboot');
53187
+ this.protocolV2LegacyDirectUpdate = this.isLegacyProtocolV2Runtime();
53188
+ this.protocolV2ExecutionInLoader = true;
53189
+ this.postTipMessage(exports.FirmwareUpdateTipMessage.GoToBootloaderSuccess);
53190
+ return false;
53191
+ }
53192
+ return this.rebootProtocolV2ToBootloader();
53193
+ });
53194
+ }
53090
53195
  waitForProtocolV2BootloaderMode(timeout = PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT, retryInterval = 1000) {
53091
53196
  return __awaiter(this, void 0, void 0, function* () {
53092
53197
  const startTime = Date.now();
@@ -53140,81 +53245,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53140
53245
  push(this.params.se04Binary, 'se04.bin', ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04);
53141
53246
  return entries;
53142
53247
  }
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, }) {
53248
+ executeProtocolV2SourceUpdate({ installSources, resourceSources, }) {
53189
53249
  return __awaiter(this, void 0, void 0, function* () {
53190
53250
  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
- }
53251
+ if (installSources.length > 0 || resourceSources.length > 0) {
53252
+ yield this.enterProtocolV2BootloaderMode();
53253
+ yield this.ensureProtocolV2BootResourceStagingIsEmpty();
53254
+ yield this.executeProtocolV2TransferPhase({
53255
+ installSources,
53256
+ resourceSources,
53257
+ });
53216
53258
  }
53217
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 execution has no final verification phase');
53259
+ return this.completeProtocolV2FinalVerification();
53218
53260
  });
53219
53261
  }
53220
53262
  ensureProtocolV2BootResourceStagingIsEmpty() {
@@ -53242,14 +53284,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53242
53284
  this.protocolV2BootResourceStagingSafe = true;
53243
53285
  });
53244
53286
  }
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
53287
  executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, }) {
53254
53288
  return __awaiter(this, void 0, void 0, function* () {
53255
53289
  const memoryInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
@@ -53265,7 +53299,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53265
53299
  kind: item.kind,
53266
53300
  });
53267
53301
  })));
53268
- return yield this.executeProtocolV2Phases({
53302
+ return yield this.executeProtocolV2SourceUpdate({
53269
53303
  installSources,
53270
53304
  resourceSources: [],
53271
53305
  });
@@ -53466,6 +53500,37 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53466
53500
  });
53467
53501
  return Array.from(expectedTargetIds).filter(targetId => !reportedTargetIds.has(targetId));
53468
53502
  }
53503
+ getProtocolV2ObservableTargetVersions(features) {
53504
+ const versions = new Map();
53505
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, getDeviceBootloaderVersion(features).join('.'));
53506
+ const applicationVersion = getDeviceFirmwareVersion(features).join('.');
53507
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, applicationVersion);
53508
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, applicationVersion);
53509
+ versions.set(ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR, getDeviceBLEFirmwareVersion(features).join('.'));
53510
+ const secureElementVersions = [
53511
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01, features.se01Version],
53512
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02, features.se02Version],
53513
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, features.se03Version],
53514
+ [ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, features.se04Version],
53515
+ ];
53516
+ secureElementVersions.forEach(([targetId, version]) => {
53517
+ if (version)
53518
+ versions.set(targetId, version);
53519
+ });
53520
+ return versions;
53521
+ }
53522
+ hasProtocolV2InstallVersionChanged(expectedTargetIds) {
53523
+ if (!this.protocolV2LastRuntimeProbeFeatures)
53524
+ return false;
53525
+ const currentVersions = this.getProtocolV2ObservableTargetVersions(this.protocolV2LastRuntimeProbeFeatures);
53526
+ return Array.from(expectedTargetIds).some(targetId => {
53527
+ const previousVersion = this.protocolV2InstallBaselineVersions.get(targetId);
53528
+ const currentVersion = currentVersions.get(targetId);
53529
+ return (previousVersion !== undefined &&
53530
+ currentVersion !== undefined &&
53531
+ previousVersion !== currentVersion);
53532
+ });
53533
+ }
53469
53534
  waitForProtocolV2FirmwareUpdateComplete(targets) {
53470
53535
  var _a, _b;
53471
53536
  return __awaiter(this, void 0, void 0, function* () {
@@ -53478,11 +53543,14 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53478
53543
  let deviceInfo;
53479
53544
  let missingTargetStatusSince;
53480
53545
  let missingTargetStatusKey;
53546
+ let normalModeWithoutInstallEvidenceSince;
53547
+ let installEvidenceObserved = this.protocolV2InstallAckReceived;
53481
53548
  const resetMissingTargetStatusGrace = () => {
53482
53549
  missingTargetStatusSince = undefined;
53483
53550
  missingTargetStatusKey = undefined;
53484
53551
  };
53485
53552
  while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
53553
+ this.throwIfAborted();
53486
53554
  try {
53487
53555
  if (shouldReconnect) {
53488
53556
  yield this.reconnectProtocolV2Device();
@@ -53499,16 +53567,26 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53499
53567
  },
53500
53568
  }, { timeoutMs: PROTOCOL_V2_FIRMWARE_STATUS_RESPONSE_TIMEOUT });
53501
53569
  const statusTargets = ((_a = statusResponse.message.records) !== null && _a !== void 0 ? _a : []);
53570
+ if (statusTargets.some(target => {
53571
+ const targetId = normalizeProtocolV2TargetId(target.target_id);
53572
+ return targetId !== undefined && expectedTargetIds.has(targetId);
53573
+ })) {
53574
+ installEvidenceObserved = true;
53575
+ normalModeWithoutInstallEvidenceSince = undefined;
53576
+ }
53502
53577
  if (this.assertProtocolV2TargetStatus(statusTargets, expectedTargetIds, expectedPaths)) {
53503
53578
  this.protocolV2FinalStatusVerified = true;
53504
53579
  return;
53505
53580
  }
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;
53581
+ if (statusTargets.length === 0 && currentDeviceInfo) {
53582
+ const isNormalMode = yield this.probeProtocolV2NormalMode(currentDeviceInfo);
53583
+ if (isNormalMode &&
53584
+ (installEvidenceObserved ||
53585
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds))) {
53586
+ Log$6.log('[FirmwareUpdateV4] empty firmware status after confirmed App reboot; update complete');
53587
+ this.postProgressMessage(100, 'installingFirmware');
53588
+ return;
53589
+ }
53512
53590
  }
53513
53591
  const missingTargetIds = this.getProtocolV2MissingTargetIds(statusTargets, expectedTargetIds);
53514
53592
  if (missingTargetIds.length > 0) {
@@ -53541,12 +53619,27 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53541
53619
  if (!currentDeviceInfo) {
53542
53620
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Protocol V2 device identity is unavailable during install polling');
53543
53621
  }
53544
- if (yield this.probeProtocolV2NormalMode(currentDeviceInfo)) {
53622
+ const isNormalMode = yield this.probeProtocolV2NormalMode(currentDeviceInfo);
53623
+ if (isNormalMode &&
53624
+ (installEvidenceObserved ||
53625
+ this.hasProtocolV2InstallVersionChanged(expectedTargetIds))) {
53545
53626
  Log$6.log('[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot');
53546
53627
  this.postProgressMessage(100, 'installingFirmware');
53547
53628
  return;
53548
53629
  }
53549
- lastError = new Error('Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode');
53630
+ if (isNormalMode) {
53631
+ const now = Date.now();
53632
+ normalModeWithoutInstallEvidenceSince !== null && normalModeWithoutInstallEvidenceSince !== void 0 ? normalModeWithoutInstallEvidenceSince : (normalModeWithoutInstallEvidenceSince = now);
53633
+ if (now - normalModeWithoutInstallEvidenceSince >=
53634
+ PROTOCOL_V2_MISSING_TARGET_STATUS_GRACE_TIMEOUT) {
53635
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareError, 'Protocol V2 device returned to normal mode without install ACK, target status, or version change');
53636
+ }
53637
+ lastError = new Error('Protocol V2 device is in normal mode but installation is not yet confirmed');
53638
+ }
53639
+ else {
53640
+ normalModeWithoutInstallEvidenceSince = undefined;
53641
+ lastError = new Error('Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode');
53642
+ }
53550
53643
  }
53551
53644
  else {
53552
53645
  shouldReconnect = true;
@@ -53598,6 +53691,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53598
53691
  probeProtocolV2NormalMode(deviceInfo) {
53599
53692
  return __awaiter(this, void 0, void 0, function* () {
53600
53693
  const features = yield this.device.probeProtocolV2RuntimeState(deviceInfo, PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT);
53694
+ this.protocolV2LastRuntimeProbeFeatures = features;
53601
53695
  return features.mode === 'normal' && !features.bootloaderMode;
53602
53696
  });
53603
53697
  }
@@ -53776,8 +53870,43 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
53776
53870
  }
53777
53871
  protocolV2StartFirmwareUpdate({ targets, }) {
53778
53872
  return __awaiter(this, void 0, void 0, function* () {
53779
- const commands = this.device.getCommands();
53780
- const response = yield commands.typedCall('DeviceFirmwareUpdateRequest', 'Success', { targets }, { timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT });
53873
+ this.protocolV2InstallAckReceived = false;
53874
+ this.protocolV2LastRuntimeProbeFeatures = undefined;
53875
+ const startUpdate = () => this.device
53876
+ .getCommands()
53877
+ .typedCall('DeviceFirmwareUpdateRequest', 'Success', { targets }, { timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT });
53878
+ let response;
53879
+ try {
53880
+ response = yield startUpdate();
53881
+ this.protocolV2InstallAckReceived = true;
53882
+ }
53883
+ catch (error) {
53884
+ if (this.isBleReconnect() && isProtocolV2BleInstallInterruptionError(error)) {
53885
+ this.throwIfAborted();
53886
+ Log$6.log('[FirmwareUpdateV4] install request interrupted by device reboot; continue status polling: ', error);
53887
+ }
53888
+ else if (this.protocolV2LegacyDirectUpdate &&
53889
+ isProtocolV2FirmwareUpdateEndpointUnavailable(error)) {
53890
+ this.protocolV2LegacyDirectUpdate = false;
53891
+ Log$6.debug('[FirmwareUpdateV4] legacy App does not expose DeviceFirmwareUpdateRequest; rebooting to bootloader');
53892
+ yield this.rebootProtocolV2ToBootloader();
53893
+ try {
53894
+ response = yield startUpdate();
53895
+ this.protocolV2InstallAckReceived = true;
53896
+ }
53897
+ catch (retryError) {
53898
+ if (!(this.isBleReconnect() && isProtocolV2BleInstallInterruptionError(retryError))) {
53899
+ throw retryError;
53900
+ }
53901
+ this.throwIfAborted();
53902
+ Log$6.log('[FirmwareUpdateV4] install request interrupted after legacy reboot; continue status polling: ', retryError);
53903
+ }
53904
+ }
53905
+ else {
53906
+ throw error;
53907
+ }
53908
+ }
53909
+ this.protocolV2LegacyDirectUpdate = false;
53781
53910
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdating);
53782
53911
  this.postProgressMessage(0, 'installingFirmware');
53783
53912
  return response;
@@ -53913,6 +54042,61 @@ class DeviceGetOnboardingStatus extends BaseMethod {
53913
54042
  }
53914
54043
  }
53915
54044
 
54045
+ const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
54046
+ const JPEG_CONTAINER_OVERHEAD_BYTES = 64 * 1024;
54047
+ const JPEG_MAX_MEMORY_USAGE_IN_MB = 32;
54048
+ const JPEG_MAX_RESOLUTION_IN_MP = 1;
54049
+ function decodeCanonicalBase64({ value, parameterName, maxBytes, }) {
54050
+ if (typeof value !== 'string' || value.length === 0) {
54051
+ throw invalidParameter$1(`Parameter [${parameterName}] must be a non-empty Base64 string.`);
54052
+ }
54053
+ if (value.length > Math.ceil(maxBytes / 3) * 4) {
54054
+ throw invalidParameter$1(`Parameter [${parameterName}] exceeds the maximum supported size.`);
54055
+ }
54056
+ if (value.length % 4 !== 0 || !BASE64_PATTERN.test(value)) {
54057
+ throw invalidParameter$1(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
54058
+ }
54059
+ const decoded = buffer.Buffer.from(value, 'base64');
54060
+ if (decoded.byteLength === 0 || decoded.byteLength > maxBytes) {
54061
+ throw invalidParameter$1(`Parameter [${parameterName}] exceeds the maximum supported size.`);
54062
+ }
54063
+ if (decoded.toString('base64') !== value) {
54064
+ throw invalidParameter$1(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
54065
+ }
54066
+ return Uint8Array.from(decoded);
54067
+ }
54068
+ function decodeJpegBase64ToRgba({ jpegBase64, parameterName, expectedWidth, expectedHeight, }) {
54069
+ const jpegBytes = decodeCanonicalBase64({
54070
+ value: jpegBase64,
54071
+ parameterName,
54072
+ maxBytes: expectedWidth * expectedHeight * 8 + JPEG_CONTAINER_OVERHEAD_BYTES,
54073
+ });
54074
+ if (jpegBytes[0] !== 0xff || jpegBytes[1] !== 0xd8) {
54075
+ throw invalidParameter$1(`Parameter [${parameterName}] must contain a JPEG image.`);
54076
+ }
54077
+ let decoded;
54078
+ try {
54079
+ decoded = jpegJs.decode(jpegBytes, {
54080
+ useTArray: true,
54081
+ formatAsRGBA: true,
54082
+ tolerantDecoding: false,
54083
+ maxResolutionInMP: JPEG_MAX_RESOLUTION_IN_MP,
54084
+ maxMemoryUsageInMB: JPEG_MAX_MEMORY_USAGE_IN_MB,
54085
+ });
54086
+ }
54087
+ catch (_a) {
54088
+ throw invalidParameter$1(`Parameter [${parameterName}] must contain a valid JPEG image.`);
54089
+ }
54090
+ if (decoded.width !== expectedWidth || decoded.height !== expectedHeight) {
54091
+ throw invalidParameter$1(`Parameter [${parameterName}] must contain a ${expectedWidth}x${expectedHeight} JPEG image.`);
54092
+ }
54093
+ const expectedLength = expectedWidth * expectedHeight * 4;
54094
+ if (decoded.data.byteLength !== expectedLength) {
54095
+ throw invalidParameter$1(`Decoded parameter [${parameterName}] must contain ${expectedLength} RGBA bytes.`);
54096
+ }
54097
+ return decoded;
54098
+ }
54099
+
53916
54100
  const Log$4 = getLogger(exports.LoggerNames.Core);
53917
54101
  const MIN_FILE_CHUNK_SIZE = 64;
53918
54102
  const FILE_TRANSFER_RATE_WINDOW_MS = 1000;
@@ -54189,6 +54373,9 @@ function writeProtocolV2File(options) {
54189
54373
 
54190
54374
  const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
54191
54375
  const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
54376
+ const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
54377
+ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2 = 60805;
54378
+ const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
54192
54379
  function normalizeFileName(fileName, data) {
54193
54380
  if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
54194
54381
  throw invalidParameter$1('Parameter [fileName] may only contain letters, numbers, underscores, hyphens and an optional .bin suffix.');
@@ -54207,26 +54394,40 @@ class DeviceUploadWallpaper extends BaseMethod {
54207
54394
  return ['V2'];
54208
54395
  }
54209
54396
  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
- }
54397
+ const { jpegBase64, fileName, chunkSize } = this.payload;
54217
54398
  if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
54218
54399
  throw invalidParameter$1('Parameter [chunkSize] must be a positive integer.');
54219
54400
  }
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 });
54401
+ const decoded = decodeJpegBase64ToRgba({
54402
+ jpegBase64,
54403
+ parameterName: 'jpegBase64',
54404
+ expectedWidth: PRO2_WALLPAPER_WIDTH,
54405
+ expectedHeight: PRO2_WALLPAPER_HEIGHT,
54406
+ });
54407
+ this.encoded = encodePro2Wallpaper({
54408
+ width: PRO2_WALLPAPER_WIDTH,
54409
+ height: PRO2_WALLPAPER_HEIGHT,
54410
+ rgba: decoded.data,
54411
+ });
54224
54412
  this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
54225
- this.params = { width, height, rgba: rgbaBytes, fileName, chunkSize };
54413
+ this.params = { jpegBase64, fileName, chunkSize };
54226
54414
  this.unlockPolicy = 'none';
54227
54415
  this.skipForceUpdateCheck = true;
54228
54416
  this.useDevicePassphraseState = false;
54229
54417
  }
54418
+ assertCapabilities() {
54419
+ return __awaiter(this, void 0, void 0, function* () {
54420
+ const protocolInfo = yield this.device.ensureProtocolV2RuntimeContext();
54421
+ const requiredMessageTypes = [
54422
+ DEVICE_SETTINGS_SET_MESSAGE_TYPE,
54423
+ FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2,
54424
+ FILESYSTEM_DIR_MAKE_MESSAGE_TYPE,
54425
+ ];
54426
+ if (requiredMessageTypes.some(messageType => !supportsProtocolV2Message(protocolInfo, messageType))) {
54427
+ throw hdShared.createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
54428
+ }
54429
+ });
54430
+ }
54230
54431
  ensureDirectory() {
54231
54432
  return __awaiter(this, void 0, void 0, function* () {
54232
54433
  if (this.directoryReady)
@@ -54276,6 +54477,7 @@ class DeviceUploadWallpaper extends BaseMethod {
54276
54477
  const { encoded } = this;
54277
54478
  if (!encoded)
54278
54479
  throw invalidParameter$1('Wallpaper data has not been initialized.');
54480
+ yield this.assertCapabilities();
54279
54481
  yield this.ensureDirectory();
54280
54482
  yield this.upload();
54281
54483
  const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
@@ -54300,7 +54502,7 @@ class DeviceUploadNft extends BaseMethod {
54300
54502
  return ['V2'];
54301
54503
  }
54302
54504
  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;
54505
+ 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
54506
  if (!Number.isInteger(chunkSize) ||
54305
54507
  chunkSize < PRO2_NFT_MIN_CHUNK_SIZE ||
54306
54508
  chunkSize > PRO2_NFT_MAX_CHUNK_SIZE) {
@@ -54312,8 +54514,51 @@ class DeviceUploadNft extends BaseMethod {
54312
54514
  if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
54313
54515
  throw invalidParameter$1('Parameter [timeoutMs] must be a positive integer.');
54314
54516
  }
54315
- this.bundle = buildPro2NftBundle({ image, thumbnail, title, subtitle, timestampMs });
54316
- this.params = { image, thumbnail, title, subtitle, timestampMs, chunkSize, paceMs, timeoutMs };
54517
+ const encodedImage = (() => {
54518
+ const decoded = decodeJpegBase64ToRgba({
54519
+ jpegBase64: imageJpegBase64,
54520
+ parameterName: 'imageJpegBase64',
54521
+ expectedWidth: PRO2_NFT_IMAGE_WIDTH,
54522
+ expectedHeight: PRO2_NFT_IMAGE_HEIGHT,
54523
+ });
54524
+ return encodePro2Image({
54525
+ width: PRO2_NFT_IMAGE_WIDTH,
54526
+ height: PRO2_NFT_IMAGE_HEIGHT,
54527
+ rgba: decoded.data,
54528
+ alphaMode: 'black-background',
54529
+ }).data;
54530
+ })();
54531
+ const encodedThumbnail = (() => {
54532
+ const decoded = decodeJpegBase64ToRgba({
54533
+ jpegBase64: thumbnailJpegBase64,
54534
+ parameterName: 'thumbnailJpegBase64',
54535
+ expectedWidth: PRO2_NFT_THUMBNAIL_WIDTH,
54536
+ expectedHeight: PRO2_NFT_THUMBNAIL_HEIGHT,
54537
+ });
54538
+ return encodePro2Image({
54539
+ width: PRO2_NFT_THUMBNAIL_WIDTH,
54540
+ height: PRO2_NFT_THUMBNAIL_HEIGHT,
54541
+ rgba: decoded.data,
54542
+ alphaMode: 'black-background',
54543
+ }).data;
54544
+ })();
54545
+ this.bundle = buildPro2NftBundleFromEncodedImages({
54546
+ image: encodedImage,
54547
+ thumbnail: encodedThumbnail,
54548
+ title,
54549
+ subtitle,
54550
+ timestampMs,
54551
+ });
54552
+ this.params = {
54553
+ imageJpegBase64,
54554
+ thumbnailJpegBase64,
54555
+ title,
54556
+ subtitle,
54557
+ timestampMs,
54558
+ chunkSize,
54559
+ paceMs,
54560
+ timeoutMs,
54561
+ };
54317
54562
  this.unlockPolicy = 'none';
54318
54563
  this.skipForceUpdateCheck = true;
54319
54564
  this.useDevicePassphraseState = false;
@@ -54456,11 +54701,17 @@ class FileWrite extends BaseMethod {
54456
54701
 
54457
54702
  const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
54458
54703
  const PORTFOLIO_CHUNK_SIZE = 2048;
54704
+ const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
54459
54705
  const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
54460
54706
  const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
54461
54707
  class UploadPortfolio extends FileWrite {
54462
54708
  init() {
54463
- const { packageBytes, timeoutMs } = this.payload;
54709
+ const { packageBase64, timeoutMs } = this.payload;
54710
+ const packageBytes = decodeCanonicalBase64({
54711
+ value: packageBase64,
54712
+ parameterName: 'packageBase64',
54713
+ maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
54714
+ });
54464
54715
  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
54716
  super.init();
54466
54717
  this.unlockPolicy = 'none';
@@ -63230,11 +63481,13 @@ class TonSignMessage extends BaseMethod {
63230
63481
  super(...arguments);
63231
63482
  this.initState = null;
63232
63483
  this.processTxRequest = (request, data) => __awaiter(this, void 0, void 0, function* () {
63484
+ var _a;
63233
63485
  if (!request.init_data_length) {
63234
63486
  const deviceType = this.device.getCurrentDeviceType();
63235
63487
  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 }));
63488
+ const signingMessage = (_a = request.signing_message) !== null && _a !== void 0 ? _a : request.signning_message;
63489
+ const shouldSkipValidation = signingMessage == null;
63490
+ return Promise.resolve(Object.assign(Object.assign({}, request), { signing_message: signingMessage, skip_validate: hasClassic || shouldSkipValidation }));
63238
63491
  }
63239
63492
  const [first, rest] = cutString(data, request.init_data_length * 2);
63240
63493
  const response = yield this.device.commands.typedCall('TonTxAck', 'TonSignedMessage', {
@@ -64785,6 +65038,7 @@ const toError = (error) => {
64785
65038
  return new Error(String(error));
64786
65039
  }
64787
65040
  };
65041
+ const isExpectedCompatibilityError = (error) => error instanceof hdShared.HardwareError && error.errorCode === hdShared.HardwareErrorCode.DeviceNotSupportMethod;
64788
65042
  const updateMethodRequestContext = (method, updates) => {
64789
65043
  if (method.requestContext) {
64790
65044
  updateRequestContext(method.requestContext.responseID, updates);
@@ -65158,7 +65412,9 @@ const onCallDevice = (context, message, method) => __awaiter(void 0, void 0, voi
65158
65412
  return yield task.callPromise.promise;
65159
65413
  }
65160
65414
  catch (e) {
65161
- Log.debug('Device Run Error: ', e);
65415
+ if (!isExpectedCompatibilityError(e)) {
65416
+ Log.debug('Device Run Error: ', e);
65417
+ }
65162
65418
  completeMethodRequestContext(method, e);
65163
65419
  return createResponseMessage(method.responseID, false, { error: e });
65164
65420
  }
@@ -65587,7 +65843,6 @@ const cleanup = () => {
65587
65843
  const pendingUiPromises = _uiPromises;
65588
65844
  _uiPromises = [];
65589
65845
  rejectUiPromises(pendingUiPromises, hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.ActionCancelled, 'UI request was cancelled'));
65590
- Log.debug('Cleanup...');
65591
65846
  };
65592
65847
  const removeDeviceListener = (device) => {
65593
65848
  device.removeAllListeners();