@onekeyfe/hd-core 1.2.0-alpha.7 → 1.2.0-alpha.9

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 (63) hide show
  1. package/__tests__/device-wallet-session-store.test.ts +131 -0
  2. package/__tests__/protocol-v2-firmware-targets.test.ts +19 -0
  3. package/__tests__/protocol-v2.test.ts +742 -536
  4. package/dist/api/ClearSessionCache.d.ts +9 -0
  5. package/dist/api/ClearSessionCache.d.ts.map +1 -0
  6. package/dist/api/FirmwareUpdateV4.d.ts +7 -6
  7. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  8. package/dist/api/firmware/getBinary.d.ts +1 -1
  9. package/dist/api/index.d.ts +3 -0
  10. package/dist/api/index.d.ts.map +1 -1
  11. package/dist/api/protocol-v2/DeviceSessionGet.d.ts +9 -0
  12. package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +1 -0
  13. package/dist/api/protocol-v2/DeviceStatusGet.d.ts +6 -0
  14. package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -0
  15. package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
  16. package/dist/api/protocol-v2/helpers.d.ts +1 -1
  17. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  18. package/dist/device/Device.d.ts +2 -2
  19. package/dist/device/Device.d.ts.map +1 -1
  20. package/dist/device/DeviceWalletSessionStore.d.ts +15 -0
  21. package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
  22. package/dist/index.d.ts +32 -19
  23. package/dist/index.js +651 -288
  24. package/dist/inject.d.ts.map +1 -1
  25. package/dist/protocols/protocol-v2/index.d.ts +1 -0
  26. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  27. package/dist/protocols/protocol-v2/walletSession.d.ts +13 -0
  28. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
  29. package/dist/types/api/firmwareUpdate.d.ts +4 -1
  30. package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
  31. package/dist/types/api/index.d.ts +6 -1
  32. package/dist/types/api/index.d.ts.map +1 -1
  33. package/dist/types/api/protocolV2.d.ts +6 -2
  34. package/dist/types/api/protocolV2.d.ts.map +1 -1
  35. package/dist/types/api/sessionCache.d.ts +10 -0
  36. package/dist/types/api/sessionCache.d.ts.map +1 -0
  37. package/dist/types/settings.d.ts +6 -14
  38. package/dist/types/settings.d.ts.map +1 -1
  39. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  40. package/dist/utils/patch.d.ts +1 -1
  41. package/dist/utils/patch.d.ts.map +1 -1
  42. package/package.json +4 -4
  43. package/src/api/ClearSessionCache.ts +28 -0
  44. package/src/api/FileRead.ts +2 -2
  45. package/src/api/FirmwareUpdateV4.ts +276 -239
  46. package/src/api/index.ts +3 -0
  47. package/src/api/protocol-v2/DeviceSessionGet.ts +26 -0
  48. package/src/api/protocol-v2/DeviceStatusGet.ts +14 -0
  49. package/src/api/protocol-v2/FilesystemFormat.ts +4 -1
  50. package/src/api/protocol-v2/helpers.ts +17 -14
  51. package/src/data/messages/messages-protocol-v2.json +134 -3
  52. package/src/data/messages/messages.json +8 -0
  53. package/src/device/Device.ts +64 -56
  54. package/src/device/DeviceWalletSessionStore.ts +78 -0
  55. package/src/inject.ts +5 -2
  56. package/src/protocols/protocol-v2/index.ts +1 -0
  57. package/src/protocols/protocol-v2/walletSession.ts +83 -0
  58. package/src/types/api/firmwareUpdate.ts +8 -2
  59. package/src/types/api/index.ts +10 -3
  60. package/src/types/api/protocolV2.ts +16 -2
  61. package/src/types/api/sessionCache.ts +14 -0
  62. package/src/types/settings.ts +14 -16
  63. package/src/utils/deviceFeaturesUtils.ts +22 -32
package/dist/index.js CHANGED
@@ -119,6 +119,7 @@ const inject = ({ call, cancel, dispose, eventEmitter, init, updateSettings, swi
119
119
  };
120
120
  const createCoreApi = (call) => ({
121
121
  getLogs: () => call({ method: 'getLogs' }),
122
+ clearSessionCache: params => call(Object.assign(Object.assign({}, params), { method: 'clearSessionCache' })),
122
123
  searchDevices: params => call(Object.assign(Object.assign({}, params), { method: 'searchDevices' })),
123
124
  getFeatures: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'getFeatures' })),
124
125
  getDeviceInfo: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'getDeviceInfo' })),
@@ -142,6 +143,8 @@ const createCoreApi = (call) => ({
142
143
  ping: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'ping' })),
143
144
  deviceReboot: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceReboot' })),
144
145
  deviceInfoGet: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceInfoGet' })),
146
+ deviceStatusGet: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceStatusGet' })),
147
+ deviceSessionGet: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceSessionGet' })),
145
148
  deviceFirmwareUpdate: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceFirmwareUpdate' })),
146
149
  deviceGetFirmwareUpdateStatus: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceGetFirmwareUpdateStatus' })),
147
150
  deviceFactoryInfoSet: (connectId, params) => call(Object.assign(Object.assign({}, params), { connectId, method: 'deviceFactoryInfoSet' })),
@@ -9277,6 +9280,14 @@ var nested$2 = {
9277
9280
  passphrase_state: {
9278
9281
  type: "string",
9279
9282
  id: 1
9283
+ },
9284
+ _only_main_pin: {
9285
+ type: "bool",
9286
+ id: 2
9287
+ },
9288
+ allow_create_attach_pin: {
9289
+ type: "bool",
9290
+ id: 3
9280
9291
  }
9281
9292
  }
9282
9293
  },
@@ -25394,8 +25405,6 @@ var nested = {
25394
25405
  MessageType_FirmwareHash: 89,
25395
25406
  MessageType_UnlockPath: 93,
25396
25407
  MessageType_UnlockedPathRequest: 94,
25397
- MessageType_UnLockDevice: 10030,
25398
- MessageType_UnLockDeviceResponse: 10031,
25399
25408
  MessageType_SetU2FCounter: 63,
25400
25409
  MessageType_GetNextU2FCounter: 80,
25401
25410
  MessageType_NextU2FCounter: 81,
@@ -25484,6 +25493,7 @@ var nested = {
25484
25493
  MessageType_EthereumGnosisSafeTxAck: 20118,
25485
25494
  MessageType_EthereumGnosisSafeTxRequest: 20119,
25486
25495
  MessageType_EthereumSignTxEIP7702OneKey: 20120,
25496
+ MessageType_EthereumSignTypedDataQR: 20121,
25487
25497
  MessageType_NEMGetAddress: 67,
25488
25498
  MessageType_NEMAddress: 68,
25489
25499
  MessageType_NEMSignTx: 69,
@@ -25741,6 +25751,8 @@ var nested = {
25741
25751
  MessageType_UiviewConfirmTxRequest: 30202,
25742
25752
  MessageType_UiviewConfirmSignMessageRequest: 30203,
25743
25753
  MessageType_UiviewResponse: 30204,
25754
+ MessageType_UnLockDevice: 10030,
25755
+ MessageType_UnLockDeviceResponse: 10031,
25744
25756
  MessageType_DeviceFactoryInfoSet: 60000,
25745
25757
  MessageType_DeviceFactoryInfoGet: 60001,
25746
25758
  MessageType_DeviceFactoryInfo: 60002,
@@ -25765,6 +25777,12 @@ var nested = {
25765
25777
  MessageType_Wallpaper: 60432,
25766
25778
  MessageType_DeviceInfoGet: 60600,
25767
25779
  MessageType_DeviceInfo: 60601,
25780
+ MessageType_DeviceStatusGet: 60602,
25781
+ MessageType_DeviceStatus: 60603,
25782
+ MessageType_DevGetOnboardingStatus: 60604,
25783
+ MessageType_DevOnboardingStatus: 60605,
25784
+ MessageType_DeviceSessionGet: 60606,
25785
+ MessageType_DeviceSession: 60607,
25768
25786
  MessageType_FilesystemPermissionFix: 60800,
25769
25787
  MessageType_FilesystemPathInfo: 60801,
25770
25788
  MessageType_FilesystemPathInfoQuery: 60802,
@@ -25779,7 +25797,8 @@ var nested = {
25779
25797
  MessageType_FilesystemFormat: 60811,
25780
25798
  MessageType_DeviceFirmwareUpdateRequest: 61000,
25781
25799
  MessageType_DeviceFirmwareUpdateStatusGet: 61001,
25782
- MessageType_DeviceFirmwareUpdateStatus: 61002
25800
+ MessageType_DeviceFirmwareUpdateStatus: 61002,
25801
+ MessageType_PortfolioUpdate: 61200
25783
25802
  },
25784
25803
  reserved: [
25785
25804
  [
@@ -30700,6 +30719,37 @@ var nested = {
30700
30719
  }
30701
30720
  }
30702
30721
  },
30722
+ EthereumSignTypedDataQR: {
30723
+ fields: {
30724
+ address_n: {
30725
+ rule: "repeated",
30726
+ type: "uint32",
30727
+ id: 1,
30728
+ options: {
30729
+ packed: false
30730
+ }
30731
+ },
30732
+ json_data: {
30733
+ type: "bytes",
30734
+ id: 2
30735
+ },
30736
+ chain_id: {
30737
+ type: "uint64",
30738
+ id: 3
30739
+ },
30740
+ metamask_v4_compat: {
30741
+ type: "bool",
30742
+ id: 4,
30743
+ options: {
30744
+ "default": true
30745
+ }
30746
+ },
30747
+ request_id: {
30748
+ type: "bytes",
30749
+ id: 5
30750
+ }
30751
+ }
30752
+ },
30703
30753
  EthereumGetPublicKeyOneKey: {
30704
30754
  fields: {
30705
30755
  address_n: {
@@ -36450,6 +36500,26 @@ var nested = {
36450
36500
  }
36451
36501
  }
36452
36502
  },
36503
+ ViewRawData: {
36504
+ fields: {
36505
+ initial_data: {
36506
+ rule: "required",
36507
+ type: "string",
36508
+ id: 1
36509
+ },
36510
+ placeholder: {
36511
+ rule: "required",
36512
+ type: "uint32",
36513
+ id: 2
36514
+ }
36515
+ }
36516
+ },
36517
+ ViewSignLayout: {
36518
+ values: {
36519
+ LayoutDefault: 0,
36520
+ LayoutSafeTxCreate: 1
36521
+ }
36522
+ },
36453
36523
  ViewSignPage: {
36454
36524
  fields: {
36455
36525
  title: {
@@ -36469,6 +36539,24 @@ var nested = {
36469
36539
  tip: {
36470
36540
  type: "ViewTip",
36471
36541
  id: 4
36542
+ },
36543
+ raw_data: {
36544
+ type: "ViewRawData",
36545
+ id: 5
36546
+ },
36547
+ slide_to_confirm: {
36548
+ type: "bool",
36549
+ id: 6,
36550
+ options: {
36551
+ "default": true
36552
+ }
36553
+ },
36554
+ layout: {
36555
+ type: "ViewSignLayout",
36556
+ id: 7,
36557
+ options: {
36558
+ "default": "LayoutDefault"
36559
+ }
36472
36560
  }
36473
36561
  }
36474
36562
  },
@@ -37227,6 +37315,48 @@ var nested = {
37227
37315
  }
37228
37316
  }
37229
37317
  },
37318
+ DeviceStatusGet: {
37319
+ fields: {
37320
+ }
37321
+ },
37322
+ DevOnboardingStage: {
37323
+ values: {
37324
+ DEV_ONBOARDING_STAGE_UNKNOWN: 0,
37325
+ DEV_ONBOARDING_STAGE_SAFETY_CHECK: 1,
37326
+ DEV_ONBOARDING_STAGE_PERSONALIZATION: 2,
37327
+ DEV_ONBOARDING_STAGE_SELECT_SETUP_METHOD: 3,
37328
+ DEV_ONBOARDING_STAGE_NEW_DEVICE: 4,
37329
+ DEV_ONBOARDING_STAGE_SELECT_RESTORE_METHOD: 5,
37330
+ DEV_ONBOARDING_STAGE_RESTORE_MNEMONIC: 6,
37331
+ DEV_ONBOARDING_STAGE_RESTORE_SEEDCARD: 7,
37332
+ DEV_ONBOARDING_STAGE_WALLET_READY: 8,
37333
+ DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP_PROMPT: 9,
37334
+ DEV_ONBOARDING_STAGE_SELECT_SEEDCARD_BACKUP_METHOD: 10,
37335
+ DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP: 11,
37336
+ DEV_ONBOARDING_STAGE_DONE: 12
37337
+ }
37338
+ },
37339
+ DevGetOnboardingStatus: {
37340
+ fields: {
37341
+ }
37342
+ },
37343
+ DevOnboardingStatus: {
37344
+ fields: {
37345
+ stage: {
37346
+ rule: "required",
37347
+ type: "DevOnboardingStage",
37348
+ id: 1
37349
+ },
37350
+ status_code: {
37351
+ type: "uint32",
37352
+ id: 2
37353
+ },
37354
+ detail_code: {
37355
+ type: "uint32",
37356
+ id: 3
37357
+ }
37358
+ }
37359
+ },
37230
37360
  FilesystemPermissionFix: {
37231
37361
  fields: {
37232
37362
  }
@@ -37441,6 +37571,20 @@ var nested = {
37441
37571
  }
37442
37572
  },
37443
37573
  FilesystemFormat: {
37574
+ fields: {
37575
+ data: {
37576
+ rule: "required",
37577
+ type: "bool",
37578
+ id: 1
37579
+ },
37580
+ user: {
37581
+ rule: "required",
37582
+ type: "bool",
37583
+ id: 2
37584
+ }
37585
+ }
37586
+ },
37587
+ PortfolioUpdate: {
37444
37588
  fields: {
37445
37589
  }
37446
37590
  },
@@ -38595,6 +38739,68 @@ const PROTOBUF_MESSAGE_CONFIG = {
38595
38739
  ],
38596
38740
  };
38597
38741
 
38742
+ const getErrorText = (error) => {
38743
+ if (error instanceof Error)
38744
+ return `${error.name} ${error.message}`;
38745
+ if (typeof error === 'string')
38746
+ return error;
38747
+ if (error && typeof error === 'object') {
38748
+ const record = error;
38749
+ return [record.code, record.errorCode, record.message, record.reason]
38750
+ .filter(value => value !== undefined && value !== null)
38751
+ .join(' ');
38752
+ }
38753
+ return String(error !== null && error !== void 0 ? error : '');
38754
+ };
38755
+ const isProtocolV2InvalidSessionError = (error) => getErrorText(error).toLowerCase().includes('failure_invalidsession');
38756
+ function requestProtocolV2DeviceStatus(device) {
38757
+ return __awaiter(this, void 0, void 0, function* () {
38758
+ const { message } = yield device.commands.typedCall('DeviceStatusGet', 'DeviceStatus', {});
38759
+ return message;
38760
+ });
38761
+ }
38762
+ function refreshProtocolV2DeviceStatus(device) {
38763
+ return __awaiter(this, void 0, void 0, function* () {
38764
+ const status = yield requestProtocolV2DeviceStatus(device);
38765
+ return device.updateProtocolV2Status(status);
38766
+ });
38767
+ }
38768
+ function getProtocolV2WalletSession(device, options) {
38769
+ var _a, _b, _c, _d, _e;
38770
+ return __awaiter(this, void 0, void 0, function* () {
38771
+ if (((_a = device.features) === null || _a === void 0 ? void 0 : _a.unlocked) === false) {
38772
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Device is locked');
38773
+ }
38774
+ if (options === null || options === void 0 ? void 0 : options.initSession) {
38775
+ device.clearInternalState();
38776
+ }
38777
+ const cachedSessionId = typeof device.getInternalState === 'function' ? device.getInternalState() : undefined;
38778
+ try {
38779
+ const { message } = yield device.commands.typedCall('DeviceSessionGet', 'DeviceSession', cachedSessionId ? { session_id: cachedSessionId } : {});
38780
+ if ((options === null || options === void 0 ? void 0 : options.expectedPassphraseState) &&
38781
+ options.expectedPassphraseState !== message.btc_test_address) {
38782
+ device.clearInternalState();
38783
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceCheckPassphraseStateError);
38784
+ }
38785
+ if (message.btc_test_address && device.getCurrentPassphraseProtection() !== true) {
38786
+ yield refreshProtocolV2DeviceStatus(device);
38787
+ }
38788
+ device.updateInternalState(((_b = device.getCurrentPassphraseProtection()) !== null && _b !== void 0 ? _b : false) || Boolean(message.btc_test_address), message.btc_test_address, device.getCurrentDeviceId(), message.session_id, (options === null || options === void 0 ? void 0 : options.initSession) ? null : (_c = device.features) === null || _c === void 0 ? void 0 : _c.sessionId);
38789
+ return {
38790
+ passphraseState: message.btc_test_address,
38791
+ newSession: message.session_id,
38792
+ unlockedAttachPin: (_e = (_d = device.features) === null || _d === void 0 ? void 0 : _d.unlockedAttachPin) !== null && _e !== void 0 ? _e : undefined,
38793
+ };
38794
+ }
38795
+ catch (error) {
38796
+ if (isProtocolV2InvalidSessionError(error)) {
38797
+ device.clearInternalState();
38798
+ }
38799
+ throw error;
38800
+ }
38801
+ });
38802
+ }
38803
+
38598
38804
  const getSupportProtocolV1MessageSchema = (features) => {
38599
38805
  var _a;
38600
38806
  if (!features)
@@ -38635,6 +38841,19 @@ const supportInputPinOnSoftware = (features) => {
38635
38841
  };
38636
38842
  const getPassphraseStateWithRefreshDeviceInfo = (device, options) => __awaiter(void 0, void 0, void 0, function* () {
38637
38843
  var _a, _b, _c;
38844
+ if (device.isProtocolV2()) {
38845
+ if (!device.features) {
38846
+ return {
38847
+ passphraseState: undefined,
38848
+ newSession: undefined,
38849
+ unlockedAttachPin: undefined,
38850
+ };
38851
+ }
38852
+ return getProtocolV2WalletSession(device, {
38853
+ initSession: options === null || options === void 0 ? void 0 : options.initSession,
38854
+ expectedPassphraseState: options === null || options === void 0 ? void 0 : options.expectPassphraseState,
38855
+ });
38856
+ }
38638
38857
  const { features } = device;
38639
38858
  const locked = (features === null || features === void 0 ? void 0 : features.unlocked) === false;
38640
38859
  const deviceType = device.getCurrentDeviceType();
@@ -38660,31 +38879,20 @@ const getPassphraseStateWithRefreshDeviceInfo = (device, options) => __awaiter(v
38660
38879
  });
38661
38880
  const supportProSeriesAttachPinPassphrase = (deviceType, firmwareVersion) => deviceType === hdShared.EDeviceType.Pro && semver__default["default"].gte(firmwareVersion, '4.15.0');
38662
38881
  const getPassphraseState = (device, options) => __awaiter(void 0, void 0, void 0, function* () {
38663
- var _d, _e;
38882
+ var _d;
38664
38883
  const { features, commands } = device;
38665
38884
  if (!features)
38666
38885
  return { passphraseState: undefined, newSession: undefined, unlockedAttachPin: undefined };
38667
38886
  const firmwareVersion = (_d = device.getCurrentFirmwareVersionString()) !== null && _d !== void 0 ? _d : '0.0.0';
38668
38887
  const deviceType = device.getCurrentDeviceType();
38669
38888
  if (device.isProtocolV2()) {
38670
- const payload = {};
38671
- const cachedSessionId = typeof device.getInternalState === 'function' ? device.getInternalState() : undefined;
38672
- if (cachedSessionId) {
38673
- payload.session_id = cachedSessionId;
38674
- }
38675
- const { message, type } = yield commands.typedCall('DeviceSessionGet', 'DeviceSession', payload);
38676
- if (type === 'CallMethodError') {
38677
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Get the passphrase state error');
38678
- }
38679
- return {
38680
- passphraseState: message.btc_test_address,
38681
- newSession: message.session_id,
38682
- unlockedAttachPin: (_e = features.unlockedAttachPin) !== null && _e !== void 0 ? _e : undefined,
38683
- };
38889
+ return getProtocolV2WalletSession(device, {
38890
+ initSession: options === null || options === void 0 ? void 0 : options.initSession,
38891
+ expectedPassphraseState: options === null || options === void 0 ? void 0 : options.expectPassphraseState,
38892
+ });
38684
38893
  }
38685
38894
  const supportAttachPinCapability = existCapability(features, hdTransport.Enum_Capability.Capability_AttachToPin);
38686
- const supportGetPassphraseState = supportAttachPinCapability ||
38687
- supportProSeriesAttachPinPassphrase(deviceType, firmwareVersion);
38895
+ const supportGetPassphraseState = supportAttachPinCapability || supportProSeriesAttachPinPassphrase(deviceType, firmwareVersion);
38688
38896
  if (supportGetPassphraseState) {
38689
38897
  const payload = (options === null || options === void 0 ? void 0 : options.onlyMainPin)
38690
38898
  ? { _only_main_pin: true }
@@ -40504,6 +40712,85 @@ class DeviceCommands {
40504
40712
  }
40505
40713
  }
40506
40714
 
40715
+ class DeviceWalletSessionStore {
40716
+ constructor() {
40717
+ this.walletSessions = new Map();
40718
+ this.pendingSessions = new Map();
40719
+ }
40720
+ get(deviceKey, passphraseState) {
40721
+ var _a;
40722
+ if (!deviceKey || !passphraseState)
40723
+ return undefined;
40724
+ return (_a = this.walletSessions.get(deviceKey)) === null || _a === void 0 ? void 0 : _a.get(passphraseState);
40725
+ }
40726
+ set(deviceKey, passphraseState, sessionId) {
40727
+ if (!deviceKey || !passphraseState || !sessionId)
40728
+ return;
40729
+ let deviceSessions = this.walletSessions.get(deviceKey);
40730
+ if (!deviceSessions) {
40731
+ deviceSessions = new Map();
40732
+ this.walletSessions.set(deviceKey, deviceSessions);
40733
+ }
40734
+ deviceSessions.set(passphraseState, sessionId);
40735
+ }
40736
+ setPending(deviceKey, sessionId) {
40737
+ if (!deviceKey || !sessionId)
40738
+ return;
40739
+ this.pendingSessions.set(deviceKey, sessionId);
40740
+ }
40741
+ getPending(deviceKey) {
40742
+ if (!deviceKey)
40743
+ return undefined;
40744
+ return this.pendingSessions.get(deviceKey);
40745
+ }
40746
+ delete(deviceKey, passphraseState) {
40747
+ if (!deviceKey || !passphraseState)
40748
+ return;
40749
+ const deviceSessions = this.walletSessions.get(deviceKey);
40750
+ if (!deviceSessions)
40751
+ return;
40752
+ deviceSessions.delete(passphraseState);
40753
+ if (deviceSessions.size === 0) {
40754
+ this.walletSessions.delete(deviceKey);
40755
+ }
40756
+ }
40757
+ deletePending(deviceKey) {
40758
+ if (!deviceKey)
40759
+ return;
40760
+ this.pendingSessions.delete(deviceKey);
40761
+ }
40762
+ deleteDevice(deviceKey) {
40763
+ if (!deviceKey)
40764
+ return;
40765
+ this.walletSessions.delete(deviceKey);
40766
+ this.pendingSessions.delete(deviceKey);
40767
+ }
40768
+ migrateDeviceKey(from, to) {
40769
+ var _a;
40770
+ if (!from || !to || from === to)
40771
+ return;
40772
+ const sourceSessions = this.walletSessions.get(from);
40773
+ if (sourceSessions) {
40774
+ const targetSessions = (_a = this.walletSessions.get(to)) !== null && _a !== void 0 ? _a : new Map();
40775
+ this.walletSessions.set(to, targetSessions);
40776
+ sourceSessions.forEach((sessionId, passphraseState) => {
40777
+ targetSessions.set(passphraseState, sessionId);
40778
+ });
40779
+ this.walletSessions.delete(from);
40780
+ }
40781
+ const pendingSession = this.pendingSessions.get(from);
40782
+ if (pendingSession) {
40783
+ this.pendingSessions.set(to, pendingSession);
40784
+ this.pendingSessions.delete(from);
40785
+ }
40786
+ }
40787
+ clear() {
40788
+ this.walletSessions.clear();
40789
+ this.pendingSessions.clear();
40790
+ }
40791
+ }
40792
+ const deviceWalletSessionStore = new DeviceWalletSessionStore();
40793
+
40507
40794
  const isProtocolV2BootloaderDeviceInfo = (deviceInfo) => !!deviceInfo && deviceInfo.status == null;
40508
40795
  const PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST = {
40509
40796
  targets: {
@@ -41076,10 +41363,8 @@ const parseRunOptions = (options) => {
41076
41363
  return options;
41077
41364
  };
41078
41365
  const Log$c = getLogger(exports.LoggerNames.Device);
41079
- const deviceSessionCache = {};
41080
41366
  function preloadSessionCache(deviceId, passphraseState, sessionId) {
41081
- const key = `${deviceId}@${passphraseState}`;
41082
- deviceSessionCache[key] = sessionId;
41367
+ deviceWalletSessionStore.set(deviceId, passphraseState, sessionId);
41083
41368
  }
41084
41369
  class Device extends events.exports {
41085
41370
  constructor(descriptor, sdkInstanceId) {
@@ -41116,7 +41401,7 @@ class Device extends events.exports {
41116
41401
  const serialNo = this.getCurrentSerialNo();
41117
41402
  const connectId = this.getConnectId();
41118
41403
  const deviceId = this.getCurrentDeviceId() || null;
41119
- const features = this.features;
41404
+ const { features } = this;
41120
41405
  return {
41121
41406
  connectId: DataManager.isBleConnect(env) ? this.mainId || null : connectId,
41122
41407
  uuid: serialNo,
@@ -41406,12 +41691,6 @@ class Device extends events.exports {
41406
41691
  support: Boolean(firmwareVersion && semver__default["default"].gte(firmwareVersion, '3.4.0')),
41407
41692
  };
41408
41693
  }
41409
- generateStateKey(deviceId, passphraseState) {
41410
- if (passphraseState) {
41411
- return `${deviceId}@${passphraseState}`;
41412
- }
41413
- return deviceId;
41414
- }
41415
41694
  getSessionCacheDeviceKey(_deviceId) {
41416
41695
  const deviceId = _deviceId || this.getCurrentDeviceId();
41417
41696
  if (deviceId)
@@ -41423,60 +41702,48 @@ class Device extends events.exports {
41423
41702
  }
41424
41703
  getInternalState(_deviceId) {
41425
41704
  var _a;
41426
- Log$c.debug('getInternalState session cache: ', deviceSessionCache);
41427
41705
  Log$c.debug('getInternalState session param: ', `device_id: ${_deviceId}`, `features.deviceId: ${(_a = this.features) === null || _a === void 0 ? void 0 : _a.deviceId}`, `passphraseState: ${this.passphraseState}`);
41428
41706
  const deviceId = this.getSessionCacheDeviceKey(_deviceId);
41429
41707
  if (!deviceId)
41430
41708
  return undefined;
41431
41709
  if (!this.passphraseState)
41432
41710
  return undefined;
41433
- const usePassKey = this.generateStateKey(deviceId, this.passphraseState);
41434
- return deviceSessionCache[usePassKey];
41711
+ return deviceWalletSessionStore.get(deviceId, this.passphraseState);
41435
41712
  }
41436
41713
  updateInternalState(enablePassphrase, passphraseState, deviceId, sessionId = null, featuresSessionId = null) {
41437
- Log$c.debug('updateInternalState session param: ', `device_id: ${deviceId}`, `enablePassphrase: ${enablePassphrase}`, `passphraseState: ${passphraseState}`, `sessionId: ${sessionId}`, `featuresSessionId: ${featuresSessionId}`);
41714
+ Log$c.debug('updateInternalState session param: ', `device_id: ${deviceId}`, `enablePassphrase: ${enablePassphrase}`, `passphraseState: ${passphraseState}`, `hasSessionId: ${Boolean(sessionId)}`, `hasFeaturesSessionId: ${Boolean(featuresSessionId)}`);
41438
41715
  const cacheDeviceKey = this.getSessionCacheDeviceKey(deviceId);
41439
41716
  if (!cacheDeviceKey)
41440
41717
  return;
41441
41718
  if (enablePassphrase) {
41442
- if (sessionId) {
41443
- deviceSessionCache[this.generateStateKey(cacheDeviceKey, passphraseState)] = sessionId;
41444
- }
41445
- else if (featuresSessionId) {
41446
- deviceSessionCache[this.generateStateKey(cacheDeviceKey, passphraseState)] =
41447
- featuresSessionId;
41448
- }
41719
+ const walletSessionId = sessionId || featuresSessionId || deviceWalletSessionStore.getPending(cacheDeviceKey);
41720
+ deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId !== null && walletSessionId !== void 0 ? walletSessionId : undefined);
41449
41721
  }
41450
- const oldKey = `${cacheDeviceKey}`;
41451
- if (deviceSessionCache[oldKey]) {
41452
- delete deviceSessionCache[oldKey];
41453
- }
41454
- Log$c.debug('updateInternalState session cache: ', deviceSessionCache);
41722
+ deviceWalletSessionStore.deletePending(cacheDeviceKey);
41455
41723
  }
41456
41724
  setInternalState(state, initSession) {
41457
41725
  var _a;
41458
- Log$c.debug('setInternalState session param: ', `state: ${state}`, `initSession: ${initSession}`, `deviceId: ${(_a = this.features) === null || _a === void 0 ? void 0 : _a.deviceId}`, `passphraseState: ${this.passphraseState}`);
41726
+ Log$c.debug('setInternalState session param: ', `hasState: ${Boolean(state)}`, `initSession: ${initSession}`, `deviceId: ${(_a = this.features) === null || _a === void 0 ? void 0 : _a.deviceId}`, `passphraseState: ${this.passphraseState}`);
41459
41727
  if (!this.passphraseState && !initSession)
41460
41728
  return;
41461
41729
  const deviceId = this.getSessionCacheDeviceKey();
41462
41730
  if (!deviceId)
41463
41731
  return;
41464
- const key = this.generateStateKey(deviceId, this.passphraseState);
41465
- if (state) {
41466
- deviceSessionCache[key] = state;
41732
+ if (this.passphraseState) {
41733
+ deviceWalletSessionStore.set(deviceId, this.passphraseState, state);
41734
+ }
41735
+ else if (initSession) {
41736
+ deviceWalletSessionStore.setPending(deviceId, state);
41467
41737
  }
41468
- Log$c.debug('setInternalState done session cache: ', deviceSessionCache);
41469
41738
  }
41470
41739
  clearInternalState(_deviceId) {
41471
41740
  Log$c.debug('clearInternalState param: ', _deviceId);
41472
41741
  const deviceId = this.getSessionCacheDeviceKey(_deviceId);
41473
41742
  if (!deviceId)
41474
41743
  return;
41475
- const key = `${deviceId}`;
41476
- delete deviceSessionCache[key];
41744
+ deviceWalletSessionStore.deletePending(deviceId);
41477
41745
  if (this.passphraseState) {
41478
- const usePassKey = this.generateStateKey(deviceId, this.passphraseState);
41479
- delete deviceSessionCache[usePassKey];
41746
+ deviceWalletSessionStore.delete(deviceId, this.passphraseState);
41480
41747
  }
41481
41748
  }
41482
41749
  initialize(options) {
@@ -41578,28 +41845,44 @@ class Device extends events.exports {
41578
41845
  }
41579
41846
  _updateFeatures(protoFeatures, initSession) {
41580
41847
  var _a, _b;
41848
+ const previousCacheDeviceKey = this.getSessionCacheDeviceKey();
41581
41849
  let feat = 'protocol' in protoFeatures
41582
41850
  ? protoFeatures
41583
41851
  : buildProtocolV1FeaturesPayload(protoFeatures, this.features);
41584
41852
  if (((_a = this.features) === null || _a === void 0 ? void 0 : _a.sessionId) && !feat.sessionId) {
41585
41853
  feat.sessionId = this.features.sessionId;
41586
41854
  }
41587
- if (this.getCurrentDeviceId() && feat.sessionId) {
41588
- this.setInternalState(feat.sessionId, initSession);
41589
- }
41590
41855
  feat.unlocked = (_b = feat.unlocked) !== null && _b !== void 0 ? _b : true;
41591
41856
  feat = fixFeaturesFirmwareVersion(feat);
41592
41857
  this.features = feat;
41858
+ const nextCacheDeviceKey = this.getSessionCacheDeviceKey();
41859
+ if (previousCacheDeviceKey && nextCacheDeviceKey) {
41860
+ deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
41861
+ }
41862
+ if (feat.deviceId && feat.sessionId) {
41863
+ this.setInternalState(feat.sessionId, initSession);
41864
+ }
41593
41865
  this.featuresNeedsReload = false;
41594
41866
  this.emit(DEVICE.FEATURES, this, feat);
41595
41867
  }
41596
41868
  updateProtocolV2Features(deviceInfo) {
41869
+ const previousCacheDeviceKey = this.getSessionCacheDeviceKey();
41597
41870
  const features = fixFeaturesFirmwareVersion(buildProtocolV2FeaturesPayload(deviceInfo, this.features));
41598
41871
  this.features = features;
41872
+ const nextCacheDeviceKey = this.getSessionCacheDeviceKey();
41873
+ if (previousCacheDeviceKey && nextCacheDeviceKey) {
41874
+ deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
41875
+ }
41599
41876
  this.featuresNeedsReload = false;
41600
41877
  this.emit(DEVICE.FEATURES, this, features);
41601
41878
  return features;
41602
41879
  }
41880
+ updateProtocolV2Status(status) {
41881
+ var _a, _b, _c, _d, _e;
41882
+ const previousDeviceInfo = (_b = (_a = this.features) === null || _a === void 0 ? void 0 : _a.raw) === null || _b === void 0 ? void 0 : _b.protocolV2DeviceInfo;
41883
+ const previousStatus = previousDeviceInfo === null || previousDeviceInfo === void 0 ? void 0 : previousDeviceInfo.status;
41884
+ return this.updateProtocolV2Features(Object.assign(Object.assign({}, (previousDeviceInfo !== null && previousDeviceInfo !== void 0 ? previousDeviceInfo : {})), { protocol_version: (_e = (_c = previousDeviceInfo === null || previousDeviceInfo === void 0 ? void 0 : previousDeviceInfo.protocol_version) !== null && _c !== void 0 ? _c : (_d = this.features) === null || _d === void 0 ? void 0 : _d.protocolVersion) !== null && _e !== void 0 ? _e : 2, status: Object.assign(Object.assign({}, previousStatus), status) }));
41885
+ }
41603
41886
  updateDescriptor(descriptor, forceUpdate = false) {
41604
41887
  var _a;
41605
41888
  const env = DataManager.getSettings('env');
@@ -41837,13 +42120,27 @@ class Device extends events.exports {
41837
42120
  };
41838
42121
  }
41839
42122
  unlockDevice() {
41840
- var _a;
42123
+ var _a, _b, _c;
41841
42124
  return __awaiter(this, void 0, void 0, function* () {
41842
- const firmwareVersion = (_a = this.getCurrentFirmwareVersionString()) !== null && _a !== void 0 ? _a : '0.0.0';
42125
+ if (this.isProtocolV2()) {
42126
+ try {
42127
+ yield this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
42128
+ }
42129
+ catch (error) {
42130
+ const errorText = error instanceof Error
42131
+ ? `${error.name} ${error.message}`
42132
+ : String((_b = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error) !== null && _b !== void 0 ? _b : '');
42133
+ if (errorText.includes('Failure_UnexpectedMessage')) {
42134
+ throw hdShared.createDeviceNotSupportMethodError('deviceUnlock', this.getCurrentFirmwareType());
42135
+ }
42136
+ throw error;
42137
+ }
42138
+ return refreshProtocolV2DeviceStatus(this);
42139
+ }
42140
+ const firmwareVersion = (_c = this.getCurrentFirmwareVersionString()) !== null && _c !== void 0 ? _c : '0.0.0';
41843
42141
  const versionRange = this.getCurrentMethodVersionRange(type => this.supportUnlockVersionRange()[type]);
41844
42142
  const supportAttachPinCapability = existCapability(this.features, hdTransport.Enum_Capability.Capability_AttachToPin);
41845
- const supportUnlock = this.isProtocolV2() ||
41846
- supportAttachPinCapability ||
42143
+ const supportUnlock = supportAttachPinCapability ||
41847
42144
  (versionRange &&
41848
42145
  semver__default["default"].valid(firmwareVersion) &&
41849
42146
  semver__default["default"].gte(firmwareVersion, versionRange.min));
@@ -41860,9 +42157,6 @@ class Device extends events.exports {
41860
42157
  const features = yield this.getFeatures();
41861
42158
  return Promise.resolve(features);
41862
42159
  }
41863
- if (this.isProtocolV2()) {
41864
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'unlock device error: device firmware does not support UnLockDevice');
41865
- }
41866
42160
  const { type } = yield this.commands.typedCall('GetAddress', 'Address', {
41867
42161
  address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
41868
42162
  coin_name: 'Testnet',
@@ -42572,6 +42866,31 @@ class GetLogs extends BaseMethod {
42572
42866
  }
42573
42867
  }
42574
42868
 
42869
+ class ClearSessionCache extends BaseMethod {
42870
+ init() {
42871
+ this.useDevice = false;
42872
+ this.useDevicePassphraseState = false;
42873
+ this.skipForceUpdateCheck = true;
42874
+ this.params = {
42875
+ deviceId: this.payload.deviceId,
42876
+ passphraseState: this.payload.passphraseState,
42877
+ };
42878
+ }
42879
+ run() {
42880
+ const { deviceId, passphraseState } = this.params;
42881
+ if (!deviceId) {
42882
+ deviceWalletSessionStore.clear();
42883
+ }
42884
+ else if (!passphraseState) {
42885
+ deviceWalletSessionStore.deleteDevice(deviceId);
42886
+ }
42887
+ else {
42888
+ deviceWalletSessionStore.delete(deviceId, passphraseState);
42889
+ }
42890
+ return Promise.resolve({ cleared: true });
42891
+ }
42892
+ }
42893
+
42575
42894
  class CheckFirmwareRelease extends BaseMethod {
42576
42895
  init() {
42577
42896
  this.allowDeviceMode = [
@@ -45448,21 +45767,29 @@ function normalizeRebootType(value) {
45448
45767
  }
45449
45768
  return hdTransport.DeviceRebootType.Normal;
45450
45769
  }
45451
- const VALID_FIRMWARE_TARGET_IDS = new Set(Object.values(ProtocolV2FirmwareTargetType).filter(value => typeof value === 'number'));
45452
- const FIRMWARE_TARGET_ID_BY_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) => VALID_FIRMWARE_TARGET_IDS.has(value)
45453
- ? [[key, value]]
45454
- : []));
45770
+ const INSTALLABLE_FIRMWARE_TARGET_IDS = new Set([
45771
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
45772
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER,
45773
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1,
45774
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2,
45775
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR,
45776
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01,
45777
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02,
45778
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03,
45779
+ ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04,
45780
+ ]);
45781
+ const FIRMWARE_TARGET_ID_BY_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).flatMap(([key, value]) => INSTALLABLE_FIRMWARE_TARGET_IDS.has(value) ? [[key, value]] : []));
45455
45782
  function normalizeTargetId(value, name) {
45456
45783
  if (value === undefined || value === null) {
45457
45784
  throw invalidParameter(`Missing required parameter: ${name}`);
45458
45785
  }
45459
45786
  const named = typeof value === 'string' ? FIRMWARE_TARGET_ID_BY_NAME.get(value) : undefined;
45460
45787
  const numeric = named !== null && named !== void 0 ? named : (typeof value === 'number' ? value : Number(value));
45461
- if (Number.isSafeInteger(numeric) && VALID_FIRMWARE_TARGET_IDS.has(numeric)) {
45788
+ if (Number.isSafeInteger(numeric) && INSTALLABLE_FIRMWARE_TARGET_IDS.has(numeric)) {
45462
45789
  return numeric;
45463
45790
  }
45464
- throw invalidParameter(`Parameter [${name}] must be a valid firmware target id (one of ${[
45465
- ...VALID_FIRMWARE_TARGET_IDS,
45791
+ throw invalidParameter(`Parameter [${name}] must be an installable firmware target id (one of ${[
45792
+ ...INSTALLABLE_FIRMWARE_TARGET_IDS,
45466
45793
  ].join(', ')}).`);
45467
45794
  }
45468
45795
  function normalizeFirmwareTargets(params) {
@@ -45495,19 +45822,20 @@ const Log$4 = getLogger(exports.LoggerNames.Method);
45495
45822
  const SESSION_ERROR = 'session not found';
45496
45823
  const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 60 * 1000;
45497
45824
  const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
45498
- const PROTOCOL_V2_START_UPDATE_TIMEOUT = 60 * 1000;
45825
+ const PROTOCOL_V2_START_UPDATE_TIMEOUT = 3 * 60 * 1000;
45499
45826
  const PROTOCOL_V2_INSTALL_TIMEOUT = 5 * 60 * 1000;
45500
45827
  const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
45501
45828
  const PROTOCOL_V2_TARGET_STATUS_IN_PROGRESS = 1;
45502
45829
  const PROTOCOL_V2_TARGET_STATUS_FINISHED = 2;
45503
45830
  const PROTOCOL_V2_TARGET_STATUS_FAILED_MIN = 3;
45504
45831
  const PROTOCOL_V2_CONNECT_PROTOCOL = 'V2';
45505
- const PROTOCOL_V2_FIRMWARE_STAGING_VOLUME = 'vol1:';
45832
+ const PROTOCOL_V2_FIRMWARE_STAGING_VOLUME = 'vol0:/';
45506
45833
  const PROTOCOL_V2_MIN_FILE_CHUNK_SIZE = 64;
45507
45834
  const PROTOCOL_V2_CONNECT_RETRY_COUNT = 10;
45508
45835
  const PROTOCOL_V2_CONNECT_POLL_INTERVAL = 500;
45509
45836
  const PROTOCOL_V2_CONNECT_SINGLE_TIMEOUT = 75 * 1000;
45510
45837
  const PROTOCOL_V2_DEVICE_INFO_READY_TIMEOUT = 60 * 1000;
45838
+ const PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT = 3;
45511
45839
  const PROTOCOL_V2_OKPP_HEADER_SIZE = 0x52a0;
45512
45840
  const PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET = 0x200;
45513
45841
  const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET = 0x240;
@@ -45569,11 +45897,6 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS = {
45569
45897
  targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04,
45570
45898
  kind: 'firmware',
45571
45899
  },
45572
- CRATE: {
45573
- fileName: 'resource.bin',
45574
- targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
45575
- kind: 'resource',
45576
- },
45577
45900
  };
45578
45901
  const PROTOCOL_V2_ROMLOADER_UNSUPPORTED_MESSAGE = 'FW_MGMT_TARGET_ROMLOADER is not accepted by the current Pro2 bootloader update request. Flash romloader with the loader-specific flow instead of firmwareUpdateV4.';
45579
45902
  const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map(Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value]));
@@ -45741,7 +46064,6 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
45741
46064
  }
45742
46065
  validateParams(payload, [
45743
46066
  { name: 'chunkSize', type: 'number' },
45744
- { name: 'resourceBinaries', type: 'array', allowEmpty: true },
45745
46067
  { name: 'forcedUpdateRes', type: 'boolean' },
45746
46068
  { name: 'bootloaderBinary', type: 'buffer' },
45747
46069
  { name: 'romloaderBinary', type: 'buffer' },
@@ -45754,6 +46076,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
45754
46076
  { name: 'se04Binary', type: 'buffer' },
45755
46077
  { name: 'firmwareType', type: 'string' },
45756
46078
  { name: 'platform', type: 'string' },
46079
+ { name: 'resourceBundleFiles', type: 'array', allowEmpty: true },
45757
46080
  ]);
45758
46081
  this.params = {
45759
46082
  chunkSize: payload.chunkSize,
@@ -45767,7 +46090,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
45767
46090
  se02Binary: payload.se02Binary,
45768
46091
  se03Binary: payload.se03Binary,
45769
46092
  se04Binary: payload.se04Binary,
45770
- resourceBinaries: payload.resourceBinaries,
46093
+ resourceBundleFiles: payload.resourceBundleFiles,
45771
46094
  firmwareType: payload.firmwareType,
45772
46095
  platform: payload.platform,
45773
46096
  };
@@ -45799,18 +46122,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
45799
46122
  const deviceFeatures = yield this.getProtocolV2DeviceFeatures();
45800
46123
  const deviceFirmwareType = getFirmwareType(deviceFeatures);
45801
46124
  const firmwareType = (_a = this.params.firmwareType) !== null && _a !== void 0 ? _a : deviceFirmwareType;
45802
- let resourceBinaryMap = [];
45803
46125
  let fwBinaryMap = [];
45804
46126
  let bootloaderBinary = null;
45805
46127
  let installItems;
45806
46128
  try {
45807
46129
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartDownloadFirmware);
45808
- resourceBinaryMap = yield this.prepareResourceBinaries(firmwareType, deviceFeatures);
45809
46130
  fwBinaryMap = this.collectExplicitTargetBinaries();
45810
46131
  bootloaderBinary = this.prepareBootloaderBinary();
45811
46132
  if (!this.hasExplicitProtocolV2Payload(fwBinaryMap)) {
45812
46133
  const remoteBinaries = yield this.prepareRemoteProtocolV2Binaries(firmwareType, deviceFeatures);
45813
- resourceBinaryMap = remoteBinaries.resourceBinaryMap;
45814
46134
  bootloaderBinary = remoteBinaries.bootloaderBinary;
45815
46135
  fwBinaryMap = remoteBinaries.fwBinaryMap;
45816
46136
  installItems = remoteBinaries.installItems;
@@ -45820,13 +46140,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
45820
46140
  catch (err) {
45821
46141
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, (_b = err.message) !== null && _b !== void 0 ? _b : err);
45822
46142
  }
45823
- if (resourceBinaryMap.length === 0 && !bootloaderBinary && fwBinaryMap.length === 0) {
46143
+ const resourceBundles = this.prepareProtocolV2ResourceBundles(firmwareType, deviceFeatures);
46144
+ if (!bootloaderBinary && fwBinaryMap.length === 0 && !(resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length)) {
45824
46145
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.FirmwareUpdateDownloadFailed, 'No firmware to update');
45825
46146
  }
45826
46147
  yield this.enterProtocolV2BootloaderMode();
45827
- yield this.executeProtocolV2Update(Object.assign({ resourceBinaryMap,
45828
- fwBinaryMap,
45829
- bootloaderBinary }, (installItems ? { installItems } : undefined)));
46148
+ yield this.executeProtocolV2Update(Object.assign(Object.assign({ fwBinaryMap,
46149
+ bootloaderBinary }, (installItems ? { installItems } : undefined)), ((resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) ? { resourceBundles } : undefined)));
45830
46150
  yield this.exitProtocolV2BootloaderToNormal();
45831
46151
  const versions = yield this.waitForProtocolV2FinalFeatures();
45832
46152
  this.postTipMessage(exports.FirmwareUpdateTipMessage.FirmwareUpdateCompleted);
@@ -45847,52 +46167,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
45847
46167
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'Device features not available');
45848
46168
  });
45849
46169
  }
45850
- prepareResourceBinaries(firmwareType, features) {
45851
- var _a;
45852
- return __awaiter(this, void 0, void 0, function* () {
45853
- if ((_a = this.params.resourceBinaries) === null || _a === void 0 ? void 0 : _a.length) {
45854
- this.params.resourceBinaries.forEach((binary, index) => {
45855
- if (!(binary instanceof ArrayBuffer)) {
45856
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallMethodInvalidParameter, `Parameter [resourceBinaries.${index}] is of type invalid and should be [buffer].`);
45857
- }
45858
- });
45859
- return this.params.resourceBinaries.map((binary, index) => ({
45860
- fileName: `resource-${index + 1}.bin`,
45861
- binary,
45862
- targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
45863
- }));
45864
- }
45865
- const resourceUrl = DataManager.getSysResourcesLatestRelease({
45866
- features,
45867
- forcedUpdateRes: this.params.forcedUpdateRes,
45868
- firmwareType,
45869
- });
45870
- if (resourceUrl) {
45871
- const resource = (yield getSysResourceBinary(resourceUrl)).binary;
45872
- return [
45873
- {
45874
- fileName: 'resource.bin',
45875
- binary: resource,
45876
- targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
45877
- },
45878
- ];
45879
- }
45880
- Log$4.warn('No resource url found');
45881
- return [];
45882
- });
45883
- }
45884
46170
  prepareBootloaderBinary() {
45885
46171
  var _a;
45886
46172
  return (_a = this.params.bootloaderBinary) !== null && _a !== void 0 ? _a : null;
45887
46173
  }
45888
46174
  hasExplicitProtocolV2Payload(fwBinaryMap) {
45889
46175
  var _a;
45890
- return (!!((_a = this.params.resourceBinaries) === null || _a === void 0 ? void 0 : _a.length) ||
46176
+ return (!!((_a = this.params.resourceBundleFiles) === null || _a === void 0 ? void 0 : _a.length) ||
45891
46177
  !!this.params.bootloaderBinary ||
45892
46178
  fwBinaryMap.length > 0);
45893
46179
  }
45894
- buildProtocolV2InstallItems({ resourceBinaryMap, bootloaderBinary, fwBinaryMap, }) {
45895
- const installItems = resourceBinaryMap.map(resource => (Object.assign(Object.assign({}, resource), { kind: 'resource' })));
46180
+ buildProtocolV2InstallItems({ bootloaderBinary, fwBinaryMap, }) {
46181
+ const installItems = [];
45896
46182
  if (bootloaderBinary) {
45897
46183
  installItems.push({
45898
46184
  fileName: 'bootloader.bin',
@@ -46024,75 +46310,12 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46024
46310
  return parseProtocolV2OkppHeader(headerBytes);
46025
46311
  });
46026
46312
  }
46027
- isProtocolV2ResourcePackageMatched(pkg, manifestVersion) {
46028
- var _a, _b;
46029
- return __awaiter(this, void 0, void 0, function* () {
46030
- try {
46031
- const header = yield this.readProtocolV2DeviceFileHeader(pkg.path);
46032
- if (!header)
46033
- return false;
46034
- const expectedType = (_a = pkg.type) !== null && _a !== void 0 ? _a : 'RESC';
46035
- const expectedVersion = (_b = pkg.version) !== null && _b !== void 0 ? _b : manifestVersion;
46036
- if (header.type !== expectedType)
46037
- return false;
46038
- if (expectedVersion && compareProtocolV2Versions(header.version, expectedVersion) !== 0) {
46039
- return false;
46040
- }
46041
- const expectedPayloadHash = normalizeProtocolV2Hex(pkg.payloadHash);
46042
- if (expectedPayloadHash && header.payloadHash !== expectedPayloadHash)
46043
- return false;
46044
- const expectedHeaderHash = normalizeProtocolV2Hex(pkg.headerHash);
46045
- if (expectedHeaderHash && header.headerHash !== expectedHeaderHash)
46046
- return false;
46047
- return true;
46048
- }
46049
- catch (error) {
46050
- Log$4.log(`Protocol V2 resource package check failed for ${pkg.path}: `, error);
46051
- return false;
46052
- }
46053
- });
46054
- }
46055
- isProtocolV2ResourceManifestSatisfied(manifest) {
46056
- var _a;
46057
- return __awaiter(this, void 0, void 0, function* () {
46058
- if (!((_a = manifest === null || manifest === void 0 ? void 0 : manifest.packages) === null || _a === void 0 ? void 0 : _a.length))
46059
- return false;
46060
- for (const pkg of manifest.packages) {
46061
- if (!(yield this.isProtocolV2ResourcePackageMatched(pkg, manifest.version))) {
46062
- return false;
46063
- }
46064
- }
46065
- return true;
46066
- });
46067
- }
46068
- getProtocolV2ResourceManifest(release, component) {
46069
- var _a;
46070
- return (_a = component.resourceManifest) !== null && _a !== void 0 ? _a : release.resourceManifest;
46071
- }
46072
- getProtocolV2ResourceComponentFileName(key) {
46073
- const safeKey = key.replace(/[^a-z0-9_-]/gi, '_') || 'resource';
46074
- return `resource-${safeKey}.bin`;
46075
- }
46076
46313
  shouldInstallRemoteProtocolV2Component(release, key, component, target, features) {
46077
- return __awaiter(this, void 0, void 0, function* () {
46078
- if (target.kind === 'resource') {
46079
- if (this.params.forcedUpdateRes ||
46080
- features.bootloaderMode ||
46081
- features.mode === 'bootloader') {
46082
- return true;
46083
- }
46084
- const resourceMatched = yield this.isProtocolV2ResourceManifestSatisfied(this.getProtocolV2ResourceManifest(release, component));
46085
- if (resourceMatched) {
46086
- Log$4.log(`[FirmwareUpdateV4] skip Protocol V2 resource component ${key}; manifest matched`);
46087
- }
46088
- return !resourceMatched;
46089
- }
46090
- const versionSatisfied = this.isProtocolV2ComponentVersionSatisfied(release, component, target, features);
46091
- if (versionSatisfied) {
46092
- Log$4.log(`[FirmwareUpdateV4] skip Protocol V2 component ${key}; version is up to date`);
46093
- }
46094
- return !versionSatisfied;
46095
- });
46314
+ const versionSatisfied = this.isProtocolV2ComponentVersionSatisfied(release, component, target, features);
46315
+ if (versionSatisfied) {
46316
+ Log$4.log(`[FirmwareUpdateV4] skip Protocol V2 component ${key}; version is up to date`);
46317
+ }
46318
+ return !versionSatisfied;
46096
46319
  }
46097
46320
  downloadRemoteProtocolV2Component(key, component) {
46098
46321
  return __awaiter(this, void 0, void 0, function* () {
@@ -46107,13 +46330,11 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46107
46330
  prepareRemoteProtocolV2Binaries(firmwareType, features) {
46108
46331
  return __awaiter(this, void 0, void 0, function* () {
46109
46332
  const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
46110
- const resourceBinaryMap = [];
46111
46333
  let bootloaderBinary = null;
46112
46334
  const fwBinaryMap = [];
46113
46335
  const installItems = [];
46114
46336
  if (!release) {
46115
46337
  return {
46116
- resourceBinaryMap,
46117
46338
  bootloaderBinary,
46118
46339
  fwBinaryMap,
46119
46340
  installItems,
@@ -46122,19 +46343,10 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46122
46343
  const entries = this.getRemoteComponentEntries(release);
46123
46344
  for (const [key, component] of entries) {
46124
46345
  const target = this.getRemoteComponentTarget(key, component);
46125
- const shouldInstall = yield this.shouldInstallRemoteProtocolV2Component(release, key, component, target, features);
46346
+ const shouldInstall = this.shouldInstallRemoteProtocolV2Component(release, key, component, target, features);
46126
46347
  if (shouldInstall) {
46127
46348
  const remoteBinary = yield this.downloadRemoteProtocolV2Component(key, component);
46128
- if (remoteBinary.kind === 'resource') {
46129
- const binaryEntry = {
46130
- fileName: this.getProtocolV2ResourceComponentFileName(key),
46131
- binary: remoteBinary.binary,
46132
- targetId: remoteBinary.targetId,
46133
- };
46134
- resourceBinaryMap.push(binaryEntry);
46135
- installItems.push(Object.assign(Object.assign({}, binaryEntry), { kind: remoteBinary.kind }));
46136
- }
46137
- else if (remoteBinary.kind === 'bootloader') {
46349
+ if (remoteBinary.kind === 'bootloader') {
46138
46350
  bootloaderBinary = remoteBinary.binary;
46139
46351
  installItems.push({
46140
46352
  fileName: remoteBinary.fileName,
@@ -46155,13 +46367,117 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46155
46367
  }
46156
46368
  }
46157
46369
  return {
46158
- resourceBinaryMap,
46159
46370
  bootloaderBinary,
46160
46371
  fwBinaryMap,
46161
46372
  installItems,
46162
46373
  };
46163
46374
  });
46164
46375
  }
46376
+ prepareProtocolV2ResourceBundles(firmwareType, features) {
46377
+ var _a, _b;
46378
+ if ((_a = this.params.resourceBundleFiles) === null || _a === void 0 ? void 0 : _a.length) {
46379
+ return this.params.resourceBundleFiles.map(file => {
46380
+ var _a;
46381
+ return ({
46382
+ name: (_a = file.devicePath.split('/').pop()) !== null && _a !== void 0 ? _a : file.devicePath,
46383
+ binary: file.binary,
46384
+ devicePath: file.devicePath,
46385
+ });
46386
+ });
46387
+ }
46388
+ const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
46389
+ if (!((_b = release === null || release === void 0 ? void 0 : release.resourceBundles) === null || _b === void 0 ? void 0 : _b.length))
46390
+ return undefined;
46391
+ return release.resourceBundles.map(bundle => ({
46392
+ name: bundle.name,
46393
+ binary: new ArrayBuffer(0),
46394
+ devicePath: bundle.devicePath,
46395
+ url: bundle.url,
46396
+ version: bundle.version,
46397
+ payloadHash: bundle.payloadHash,
46398
+ headerHash: bundle.headerHash,
46399
+ }));
46400
+ }
46401
+ syncProtocolV2ResourceBundles(bundles, firmwareSize) {
46402
+ return __awaiter(this, void 0, void 0, function* () {
46403
+ const transferStartTime = Date.now();
46404
+ const transferTransport = this.getProtocolV2FirmwareTransferTransport();
46405
+ const isManualMode = bundles.every(b => b.binary.byteLength > 0);
46406
+ let bundlesToSync = bundles;
46407
+ if (!isManualMode) {
46408
+ const filtered = [];
46409
+ for (const bundle of bundles) {
46410
+ if (bundle.binary.byteLength === 0 && bundle.url) {
46411
+ Log$4.log(`[FirmwareUpdateV4] downloading RESC bundle ${bundle.name} from ${bundle.url}`);
46412
+ const { binary } = yield getSysResourceBinary(bundle.url);
46413
+ bundle.binary = binary;
46414
+ }
46415
+ const upToDate = yield this.isProtocolV2ResourceBundleUpToDate(bundle);
46416
+ if (upToDate) {
46417
+ Log$4.log(`[FirmwareUpdateV4] skip RESC bundle ${bundle.name}; already up to date`);
46418
+ }
46419
+ else {
46420
+ filtered.push(bundle);
46421
+ }
46422
+ }
46423
+ bundlesToSync = filtered;
46424
+ }
46425
+ if (bundlesToSync.length === 0) {
46426
+ Log$4.log('[FirmwareUpdateV4] all RESC bundles up to date, nothing to sync');
46427
+ return { processedSize: 0, totalSize: firmwareSize };
46428
+ }
46429
+ let totalSize = 0;
46430
+ for (const b of bundlesToSync)
46431
+ totalSize += b.binary.byteLength;
46432
+ const transferTotalSize = totalSize + firmwareSize;
46433
+ let processedSize = 0;
46434
+ for (const bundle of bundlesToSync) {
46435
+ Log$4.log(`[FirmwareUpdateV4] syncing RESC bundle ${bundle.name} -> ${bundle.devicePath} bytes=${bundle.binary.byteLength}`);
46436
+ processedSize = yield this.protocolV2CommonUpdateProcess({
46437
+ payload: bundle.binary,
46438
+ filePath: bundle.devicePath,
46439
+ processedSize,
46440
+ totalSize: transferTotalSize,
46441
+ });
46442
+ }
46443
+ const elapsedMs = Date.now() - transferStartTime;
46444
+ Log$4.log(`[FirmwareUpdateV4] RESC bundle sync finished transport=${transferTransport} bytes=${totalSize} elapsed=${(elapsedMs / 1000).toFixed(2)}s speed=${formatProtocolV2TransferSpeed(totalSize, elapsedMs)} KB/s`);
46445
+ return { processedSize, totalSize: transferTotalSize };
46446
+ });
46447
+ }
46448
+ isProtocolV2ResourceBundleUpToDate(bundle) {
46449
+ return __awaiter(this, void 0, void 0, function* () {
46450
+ if (this.params.forcedUpdateRes)
46451
+ return false;
46452
+ if (!bundle.version && !bundle.payloadHash)
46453
+ return false;
46454
+ try {
46455
+ const header = yield this.readProtocolV2DeviceFileHeader(bundle.devicePath);
46456
+ if (!header)
46457
+ return false;
46458
+ if (bundle.version) {
46459
+ const cmp = compareProtocolV2Versions(header.version, bundle.version);
46460
+ if (cmp === undefined || cmp !== 0)
46461
+ return false;
46462
+ }
46463
+ if (bundle.payloadHash) {
46464
+ const expected = normalizeProtocolV2Hex(bundle.payloadHash);
46465
+ if (expected && header.payloadHash !== expected)
46466
+ return false;
46467
+ }
46468
+ if (bundle.headerHash) {
46469
+ const expected = normalizeProtocolV2Hex(bundle.headerHash);
46470
+ if (expected && header.headerHash !== expected)
46471
+ return false;
46472
+ }
46473
+ return true;
46474
+ }
46475
+ catch (error) {
46476
+ Log$4.log(`[FirmwareUpdateV4] RESC bundle ${bundle.name} header check failed: `, error);
46477
+ return false;
46478
+ }
46479
+ });
46480
+ }
46165
46481
  isProtocolV2BootloaderMode() {
46166
46482
  var _a;
46167
46483
  if (typeof this.device.isBootloader === 'function') {
@@ -46236,19 +46552,31 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46236
46552
  push(this.params.se04Binary, 'se04.bin', ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04);
46237
46553
  return entries;
46238
46554
  }
46239
- executeProtocolV2Update({ resourceBinaryMap, fwBinaryMap, bootloaderBinary, installItems, }) {
46555
+ executeProtocolV2Update({ fwBinaryMap, bootloaderBinary, installItems, resourceBundles, }) {
46240
46556
  return __awaiter(this, void 0, void 0, function* () {
46241
46557
  const orderedInstallItems = installItems !== null && installItems !== void 0 ? installItems : this.buildProtocolV2InstallItems({
46242
- resourceBinaryMap: resourceBinaryMap !== null && resourceBinaryMap !== void 0 ? resourceBinaryMap : [],
46243
46558
  bootloaderBinary: bootloaderBinary !== null && bootloaderBinary !== void 0 ? bootloaderBinary : null,
46244
46559
  fwBinaryMap: fwBinaryMap !== null && fwBinaryMap !== void 0 ? fwBinaryMap : [],
46245
46560
  });
46246
- let totalSize = 0;
46247
- let processedSize = 0;
46248
- let transferredSize = 0;
46561
+ let firmwareSize = 0;
46249
46562
  for (const item of orderedInstallItems)
46250
- totalSize += item.binary.byteLength;
46563
+ firmwareSize += item.binary.byteLength;
46251
46564
  this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
46565
+ let processedSize = 0;
46566
+ let totalSize = firmwareSize;
46567
+ if (resourceBundles === null || resourceBundles === void 0 ? void 0 : resourceBundles.length) {
46568
+ const resourceTransfer = yield this.syncProtocolV2ResourceBundles(resourceBundles, firmwareSize);
46569
+ processedSize = resourceTransfer.processedSize;
46570
+ totalSize = resourceTransfer.totalSize;
46571
+ }
46572
+ if (orderedInstallItems.length === 0) {
46573
+ Log$4.log('[FirmwareUpdateV4] no firmware targets to install (RESC bundles only)');
46574
+ if (totalSize > 0) {
46575
+ this.postProgressMessage(100, 'transferData');
46576
+ }
46577
+ return;
46578
+ }
46579
+ let transferredSize = processedSize;
46252
46580
  const transferStartTime = Date.now();
46253
46581
  const transferTransport = this.getProtocolV2FirmwareTransferTransport();
46254
46582
  const chunkSize = this.getProtocolV2FirmwareChunkSize();
@@ -46269,6 +46597,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46269
46597
  onTransferredBytes,
46270
46598
  });
46271
46599
  transferredSize = processedSize;
46600
+ yield this.verifyProtocolV2StagedFile(filePath, item.binary.byteLength);
46272
46601
  stagedInstallTargets.push(Object.assign(Object.assign({}, item), { path: filePath }));
46273
46602
  }
46274
46603
  if (totalSize > 0) {
@@ -46283,39 +46612,29 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46283
46612
  throw error;
46284
46613
  }
46285
46614
  this.postTipMessage(exports.FirmwareUpdateTipMessage.ConfirmOnDevice);
46286
- const firmwareTargets = [];
46287
- const flushFirmwareTargets = () => __awaiter(this, void 0, void 0, function* () {
46288
- if (firmwareTargets.length === 0)
46289
- return;
46290
- const targets = firmwareTargets.splice(0, firmwareTargets.length);
46291
- Log$4.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest targets=${JSON.stringify(targets)}`);
46292
- const startResponse = yield this.protocolV2StartFirmwareUpdate({ targets });
46293
- yield this.waitForProtocolV2FirmwareUpdateComplete(targets, startResponse);
46294
- });
46295
- for (const item of stagedInstallTargets) {
46296
- const target = {
46297
- target_id: item.targetId,
46298
- path: item.path,
46299
- };
46300
- if (item.kind === 'resource') {
46301
- yield flushFirmwareTargets();
46302
- const resourceTargets = [target];
46303
- Log$4.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest resources=${JSON.stringify(resourceTargets)}`);
46304
- const startResponse = yield this.protocolV2StartFirmwareUpdate({
46305
- targets: resourceTargets,
46306
- });
46307
- yield this.waitForProtocolV2FirmwareUpdateComplete(resourceTargets, startResponse);
46308
- }
46309
- else {
46310
- firmwareTargets.push(target);
46311
- }
46312
- }
46313
- yield flushFirmwareTargets();
46615
+ const allTargets = stagedInstallTargets.map(item => ({
46616
+ target_id: item.targetId,
46617
+ path: item.path,
46618
+ }));
46619
+ Log$4.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest targets=${JSON.stringify(allTargets)}`);
46620
+ const startResponse = yield this.protocolV2StartFirmwareUpdate({ targets: allTargets });
46621
+ yield this.waitForProtocolV2FirmwareUpdateComplete(allTargets, startResponse);
46314
46622
  });
46315
46623
  }
46316
46624
  getProtocolV2InstallItemStagingPath(item) {
46317
46625
  return `${PROTOCOL_V2_FIRMWARE_STAGING_VOLUME}${item.fileName}`;
46318
46626
  }
46627
+ verifyProtocolV2StagedFile(path, expectedSize) {
46628
+ var _a, _b, _c, _d;
46629
+ return __awaiter(this, void 0, void 0, function* () {
46630
+ const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
46631
+ const response = yield typedCall('FilesystemPathInfoQuery', 'FilesystemPathInfo', { path });
46632
+ const actualSize = toProtocolV2FiniteNumber((_a = response.message) === null || _a === void 0 ? void 0 : _a.size);
46633
+ if (!((_b = response.message) === null || _b === void 0 ? void 0 : _b.exist) || ((_c = response.message) === null || _c === void 0 ? void 0 : _c.directory) || actualSize !== expectedSize) {
46634
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `staged file verification failed: path=${path} exist=${!!((_d = response.message) === null || _d === void 0 ? void 0 : _d.exist)} expected=${expectedSize} actual=${actualSize !== null && actualSize !== void 0 ? actualSize : 'unknown'}`);
46635
+ }
46636
+ });
46637
+ }
46319
46638
  queryProtocolV2FirmwareUpdateStatus() {
46320
46639
  return __awaiter(this, void 0, void 0, function* () {
46321
46640
  const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
@@ -46520,7 +46839,26 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46520
46839
  yield this.device.initialize();
46521
46840
  });
46522
46841
  }
46523
- protocolV2CommonUpdateProcess({ payload, filePath, processedSize, totalSize, onTransferredBytes, }) {
46842
+ protocolV2CommonUpdateProcess(params) {
46843
+ return __awaiter(this, void 0, void 0, function* () {
46844
+ let lastError;
46845
+ for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
46846
+ try {
46847
+ return yield this.protocolV2WriteWholeFile(params);
46848
+ }
46849
+ catch (error) {
46850
+ lastError = error;
46851
+ Log$4.error(`Protocol V2 file transfer failed path=${params.filePath} attempt=${attempt}/${PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT}; restarting from offset 0`, error);
46852
+ if (attempt === PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
46853
+ break;
46854
+ }
46855
+ yield this.recoverProtocolV2FileTransfer();
46856
+ }
46857
+ }
46858
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`);
46859
+ });
46860
+ }
46861
+ protocolV2WriteWholeFile({ payload, filePath, processedSize, totalSize, onTransferredBytes, }) {
46524
46862
  return __awaiter(this, void 0, void 0, function* () {
46525
46863
  const chunkSize = this.getProtocolV2FirmwareChunkSize();
46526
46864
  let offset = 0;
@@ -46536,7 +46874,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46536
46874
  const chunk = payload.slice(offset, chunkEnd);
46537
46875
  const overwrite = offset === 0;
46538
46876
  const progress = getProtocolV2DeviceTransferProgress((processedSize !== null && processedSize !== void 0 ? processedSize : 0) + offset, (processedSize !== null && processedSize !== void 0 ? processedSize : 0) + chunkEnd, totalSize !== null && totalSize !== void 0 ? totalSize : payload.byteLength);
46539
- const writeRes = yield this.fileWriteWithRetry(filePath, payload.byteLength, offset, chunk, overwrite, progress);
46877
+ const writeRes = yield this.fileWriteChunk(filePath, payload.byteLength, offset, chunk, overwrite, progress);
46540
46878
  const processedByte = Number(writeRes.message.processed_byte);
46541
46879
  const nextOffset = Number.isFinite(processedByte) && processedByte > offset
46542
46880
  ? processedByte
@@ -46562,54 +46900,41 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
46562
46900
  }
46563
46901
  return env !== null && env !== void 0 ? env : 'unknown';
46564
46902
  }
46565
- fileWriteWithRetry(filePath, totalFileSize, offset, chunk, overwrite, progress) {
46903
+ fileWriteChunk(filePath, totalFileSize, offset, chunk, overwrite, progress) {
46904
+ var _a;
46566
46905
  return __awaiter(this, void 0, void 0, function* () {
46567
- const writeFunc = () => __awaiter(this, void 0, void 0, function* () {
46568
- var _a;
46569
- const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
46570
- const writeRes = yield typedCall('FilesystemFileWrite', 'FilesystemFile', {
46571
- file: {
46572
- path: filePath,
46573
- offset,
46574
- total_size: totalFileSize,
46575
- data: chunk,
46576
- },
46577
- overwrite,
46578
- append: false,
46579
- ui_percentage: progress !== null && progress !== void 0 ? progress : undefined,
46580
- });
46581
- if (writeRes.type !== 'FilesystemFile') {
46582
- if (writeRes.type === 'CallMethodError') {
46583
- if (((_a = writeRes.message.error) !== null && _a !== void 0 ? _a : '').indexOf(SESSION_ERROR) > -1) {
46584
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, SESSION_ERROR);
46585
- }
46586
- }
46587
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
46588
- }
46589
- return writeRes;
46906
+ const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
46907
+ const writeRes = yield typedCall('FilesystemFileWrite', 'FilesystemFile', {
46908
+ file: {
46909
+ path: filePath,
46910
+ offset,
46911
+ total_size: totalFileSize,
46912
+ data: chunk,
46913
+ },
46914
+ overwrite,
46915
+ append: false,
46916
+ ui_percentage: progress !== null && progress !== void 0 ? progress : undefined,
46590
46917
  });
46591
- let retryCount = 10;
46592
- while (retryCount > 0) {
46593
- try {
46594
- const result = yield writeFunc();
46595
- return result;
46596
- }
46597
- catch (error) {
46598
- Log$4.error(`fileWrite error: `, error);
46599
- retryCount--;
46600
- if (retryCount === 0) {
46601
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
46918
+ if (writeRes.type !== 'FilesystemFile') {
46919
+ if (writeRes.type === 'CallMethodError') {
46920
+ if (((_a = writeRes.message.error) !== null && _a !== void 0 ? _a : '').indexOf(SESSION_ERROR) > -1) {
46921
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, SESSION_ERROR);
46602
46922
  }
46603
- const env = DataManager.getSettings('env');
46604
- if (DataManager.isBleConnect(env)) {
46605
- yield hdShared.wait(3000);
46606
- yield this.acquireProtocolV2BleDevice();
46607
- yield this.device.initialize();
46608
- }
46609
- yield hdShared.wait(2000);
46610
46923
  }
46924
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
46611
46925
  }
46612
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
46926
+ return writeRes;
46927
+ });
46928
+ }
46929
+ recoverProtocolV2FileTransfer() {
46930
+ return __awaiter(this, void 0, void 0, function* () {
46931
+ const env = DataManager.getSettings('env');
46932
+ if (DataManager.isBleConnect(env)) {
46933
+ yield hdShared.wait(3000);
46934
+ yield this.acquireProtocolV2BleDevice();
46935
+ yield this.device.initialize();
46936
+ }
46937
+ yield hdShared.wait(2000);
46613
46938
  });
46614
46939
  }
46615
46940
  acquireProtocolV2BleDevice() {
@@ -46875,6 +47200,38 @@ class DeviceInfoGet extends BaseMethod {
46875
47200
  }
46876
47201
  }
46877
47202
 
47203
+ class DeviceStatusGet extends BaseMethod {
47204
+ init() {
47205
+ this.requireProtocolV2 = true;
47206
+ this.useDevicePassphraseState = false;
47207
+ this.skipForceUpdateCheck = true;
47208
+ }
47209
+ run() {
47210
+ return __awaiter(this, void 0, void 0, function* () {
47211
+ const { message } = yield this.device.commands.typedCall('DeviceStatusGet', 'DeviceStatus', {});
47212
+ return message;
47213
+ });
47214
+ }
47215
+ }
47216
+
47217
+ class DeviceSessionGet extends BaseMethod {
47218
+ init() {
47219
+ this.requireProtocolV2 = true;
47220
+ this.useDevicePassphraseState = false;
47221
+ this.skipForceUpdateCheck = true;
47222
+ this.params = {
47223
+ sessionId: this.payload.sessionId,
47224
+ };
47225
+ }
47226
+ run() {
47227
+ return __awaiter(this, void 0, void 0, function* () {
47228
+ const payload = this.params.sessionId ? { session_id: this.params.sessionId } : {};
47229
+ const { message } = yield this.device.commands.typedCall('DeviceSessionGet', 'DeviceSession', payload);
47230
+ return message;
47231
+ });
47232
+ }
47233
+ }
47234
+
46878
47235
  class DeviceFirmwareUpdate extends BaseMethod {
46879
47236
  init() {
46880
47237
  this.requireProtocolV2 = true;
@@ -47023,7 +47380,10 @@ class FilesystemFormat extends BaseMethod {
47023
47380
  }
47024
47381
  run() {
47025
47382
  return __awaiter(this, void 0, void 0, function* () {
47026
- const res = yield this.device.commands.typedCall('FilesystemFormat', 'Success', {});
47383
+ const res = yield this.device.commands.typedCall('FilesystemFormat', 'Success', {
47384
+ data: true,
47385
+ user: true,
47386
+ });
47027
47387
  return Promise.resolve(res.message);
47028
47388
  });
47029
47389
  }
@@ -47067,7 +47427,7 @@ const MIN_FILE_READ_CHUNK_SIZE = 64;
47067
47427
  function getProtocolV2FileReadChunkLimit() {
47068
47428
  const env = DataManager.getSettings('env');
47069
47429
  if (env && DataManager.isBleConnect(env)) {
47070
- return hdTransport.PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
47430
+ return hdTransport.PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE;
47071
47431
  }
47072
47432
  return hdTransport.PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
47073
47433
  }
@@ -56617,6 +56977,7 @@ var ApiMethods = /*#__PURE__*/Object.freeze({
56617
56977
  getOnekeyFeatures: GetOnekeyFeatures,
56618
56978
  getPassphraseState: GetPassphraseState,
56619
56979
  getLogs: GetLogs,
56980
+ clearSessionCache: ClearSessionCache,
56620
56981
  checkFirmwareRelease: CheckFirmwareRelease,
56621
56982
  checkBLEFirmwareRelease: CheckBLEFirmwareRelease,
56622
56983
  checkBridgeStatus: CheckBridgeStatus,
@@ -56653,6 +57014,8 @@ var ApiMethods = /*#__PURE__*/Object.freeze({
56653
57014
  ping: Ping,
56654
57015
  deviceReboot: DeviceReboot,
56655
57016
  deviceInfoGet: DeviceInfoGet,
57017
+ deviceStatusGet: DeviceStatusGet,
57018
+ deviceSessionGet: DeviceSessionGet,
56656
57019
  deviceFirmwareUpdate: DeviceFirmwareUpdate,
56657
57020
  deviceGetFirmwareUpdateStatus: DeviceGetFirmwareUpdateStatus,
56658
57021
  deviceFactoryInfoSet: DeviceFactoryInfoSet,