@onekeyfe/hd-core 1.2.0-alpha.98 → 1.2.0

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 (204) hide show
  1. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +20 -4
  2. package/__tests__/DeviceCommands.test.ts +203 -27
  3. package/__tests__/base64Data.test.ts +69 -0
  4. package/__tests__/check-all-firmware-release-protocol-v2.test.ts +89 -38
  5. package/__tests__/check-firmware-release-protocol-v2.test.ts +83 -14
  6. package/__tests__/device-connector-protocol.test.ts +21 -0
  7. package/__tests__/device-lifecycle-events.test.ts +427 -7
  8. package/__tests__/device-pool-state.test.ts +25 -0
  9. package/__tests__/device-settings.test.ts +237 -9
  10. package/__tests__/device-state-events.test.ts +2 -2
  11. package/__tests__/device-state-mapper.test.ts +61 -5
  12. package/__tests__/device-utils.test.ts +15 -1
  13. package/__tests__/device-wallet-session-store.test.ts +147 -21
  14. package/__tests__/deviceSettings.test.ts +7 -3
  15. package/__tests__/deviceUploadNft.test.ts +36 -4
  16. package/__tests__/firmware-update/device-update-bootloader.test.ts +14 -3
  17. package/__tests__/firmware-update/firmware-artifact-source.test.ts +61 -9
  18. package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +19 -9
  19. package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +21 -0
  20. package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +128 -2
  21. package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +80 -0
  22. package/__tests__/firmware-update/firmware-update-plan.test.ts +114 -50
  23. package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +19 -5
  24. package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +116 -0
  25. package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +678 -0
  26. package/__tests__/firmware-update/firmware-update-v4-parameters.test.ts +85 -0
  27. package/__tests__/get-device-state.test.ts +60 -21
  28. package/__tests__/logBlockEvent.test.ts +13 -1
  29. package/__tests__/open-wallet-session.test.ts +127 -1
  30. package/__tests__/protocol-v2-firmware-targets.test.ts +39 -0
  31. package/__tests__/protocol-v2-resources.test.ts +185 -88
  32. package/__tests__/protocol-v2-unlock-policy.test.ts +235 -2
  33. package/__tests__/protocol-v2.test.ts +2274 -466
  34. package/__tests__/refresh-device-state.test.ts +3 -1
  35. package/__tests__/resourceBase64Boundary.test.ts +48 -0
  36. package/__tests__/search-devices.test.ts +79 -32
  37. package/__tests__/ton-sign-message.test.ts +84 -0
  38. package/dist/api/BaseMethod.d.ts +2 -1
  39. package/dist/api/BaseMethod.d.ts.map +1 -1
  40. package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
  41. package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
  42. package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
  43. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  44. package/dist/api/FirmwareUpdateV4.d.ts +22 -7
  45. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  46. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  47. package/dist/api/SearchDevices.d.ts.map +1 -1
  48. package/dist/api/UploadPortfolio.d.ts +1 -1
  49. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  50. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  51. package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
  52. package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
  53. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  54. package/dist/api/device/DeviceSettings.d.ts.map +1 -1
  55. package/dist/api/device/DeviceVerify.d.ts +1 -0
  56. package/dist/api/device/DeviceVerify.d.ts.map +1 -1
  57. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  58. package/dist/api/firmware/FirmwareArtifactSource.d.ts +5 -1
  59. package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -1
  60. package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -1
  61. package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -1
  62. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +2 -2
  63. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  64. package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -15
  65. package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
  66. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +1 -0
  67. package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
  68. package/dist/api/firmware/getBinary.d.ts +3 -2
  69. package/dist/api/firmware/getBinary.d.ts.map +1 -1
  70. package/dist/api/firmware/protocolV2Release.d.ts.map +1 -1
  71. package/dist/api/helpers/base64Data.d.ts +16 -0
  72. package/dist/api/helpers/base64Data.d.ts.map +1 -0
  73. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +3 -1
  74. package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
  75. package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
  76. package/dist/api/protocol-v2/DeviceInfoGet.d.ts +1 -1
  77. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
  78. package/dist/api/protocol-v2/DeviceReboot.d.ts +1 -1
  79. package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
  80. package/dist/api/protocol-v2/DeviceUploadNft.d.ts +2 -3
  81. package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
  82. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +2 -3
  83. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  84. package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
  85. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  86. package/dist/core/index.d.ts +6 -1
  87. package/dist/core/index.d.ts.map +1 -1
  88. package/dist/data-manager/DataManager.d.ts +4 -3
  89. package/dist/data-manager/DataManager.d.ts.map +1 -1
  90. package/dist/data-manager/TransportManager.d.ts.map +1 -1
  91. package/dist/device/Device.d.ts +16 -3
  92. package/dist/device/Device.d.ts.map +1 -1
  93. package/dist/device/DeviceCommands.d.ts +4 -4
  94. package/dist/device/DeviceCommands.d.ts.map +1 -1
  95. package/dist/device/DeviceConnector.d.ts +1 -1
  96. package/dist/device/DeviceConnector.d.ts.map +1 -1
  97. package/dist/device/DevicePool.d.ts.map +1 -1
  98. package/dist/device/DeviceStateMapper.d.ts.map +1 -1
  99. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  100. package/dist/events/logBlockEvent.d.ts.map +1 -1
  101. package/dist/events/ui-request.d.ts +3 -0
  102. package/dist/events/ui-request.d.ts.map +1 -1
  103. package/dist/index.d.ts +54 -84
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +2333 -1515
  106. package/dist/protocols/protocol-v2/features.d.ts +13 -5
  107. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  108. package/dist/protocols/protocol-v2/index.d.ts +2 -2
  109. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  110. package/dist/protocols/protocol-v2/resources.d.ts +12 -7
  111. package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
  112. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +3 -1
  113. package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -1
  114. package/dist/protocols/protocol-v2/walletSession.d.ts +3 -0
  115. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  116. package/dist/types/api/firmwareUpdatePlan.d.ts +2 -2
  117. package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -1
  118. package/dist/types/api/protocolV2.d.ts +1 -1
  119. package/dist/types/api/protocolV2.d.ts.map +1 -1
  120. package/dist/types/device.d.ts.map +1 -1
  121. package/dist/types/settings.d.ts +3 -31
  122. package/dist/types/settings.d.ts.map +1 -1
  123. package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
  124. package/dist/utils/deviceFeaturesUtils.d.ts +3 -0
  125. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  126. package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
  127. package/dist/utils/deviceSettings.d.ts +1 -0
  128. package/dist/utils/deviceSettings.d.ts.map +1 -1
  129. package/dist/utils/index.d.ts +1 -1
  130. package/dist/utils/index.d.ts.map +1 -1
  131. package/dist/utils/patch.d.ts +1 -1
  132. package/dist/utils/patch.d.ts.map +1 -1
  133. package/dist/utils/pro2Nft.d.ts +7 -0
  134. package/dist/utils/pro2Nft.d.ts.map +1 -1
  135. package/package.json +6 -4
  136. package/src/api/BaseMethod.ts +8 -1
  137. package/src/api/CheckAllFirmwareRelease.ts +8 -5
  138. package/src/api/CheckBLEFirmwareRelease.ts +2 -2
  139. package/src/api/CheckBootloaderRelease.ts +3 -2
  140. package/src/api/CheckFirmwareRelease.ts +2 -2
  141. package/src/api/FirmwareUpdateV2.ts +130 -69
  142. package/src/api/FirmwareUpdateV3.ts +29 -19
  143. package/src/api/FirmwareUpdateV4.ts +966 -743
  144. package/src/api/OpenWalletSession.ts +39 -9
  145. package/src/api/PromptWebDeviceAccess.ts +2 -2
  146. package/src/api/SearchDevices.ts +6 -3
  147. package/src/api/UploadPortfolio.ts +9 -2
  148. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +2 -1
  149. package/src/api/device/DeviceChangePin.ts +4 -1
  150. package/src/api/device/DeviceRebootToBoardloader.ts +3 -1
  151. package/src/api/device/DeviceRebootToBootloader.ts +3 -1
  152. package/src/api/device/DeviceSettings.ts +34 -20
  153. package/src/api/device/DeviceVerify.ts +25 -0
  154. package/src/api/device/DeviceWipe.ts +4 -1
  155. package/src/api/firmware/FirmwareArtifactSource.ts +41 -14
  156. package/src/api/firmware/FirmwareHostBinding.ts +10 -0
  157. package/src/api/firmware/FirmwarePreparedResourceArchive.ts +16 -27
  158. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +131 -76
  159. package/src/api/firmware/FirmwareUpdatePlan.ts +55 -82
  160. package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +32 -15
  161. package/src/api/firmware/protocolV2Release.ts +7 -2
  162. package/src/api/helpers/base64Data.ts +85 -0
  163. package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +1 -1
  164. package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +6 -28
  165. package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +7 -1
  166. package/src/api/protocol-v2/DeviceInfoGet.ts +3 -3
  167. package/src/api/protocol-v2/DeviceReboot.ts +5 -0
  168. package/src/api/protocol-v2/DeviceUploadNft.ts +61 -9
  169. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +53 -19
  170. package/src/api/protocol-v2/helpers.ts +8 -0
  171. package/src/api/ton/TonSignMessage.ts +5 -3
  172. package/src/core/index.ts +264 -55
  173. package/src/data/messages/messages-protocol-v2.json +140 -13
  174. package/src/data-manager/DataManager.ts +46 -39
  175. package/src/data-manager/TransportManager.ts +3 -1
  176. package/src/device/Device.ts +210 -44
  177. package/src/device/DeviceCommands.ts +27 -18
  178. package/src/device/DeviceConnector.ts +17 -3
  179. package/src/device/DevicePool.ts +9 -2
  180. package/src/device/DeviceStateMapper.ts +30 -24
  181. package/src/deviceProfile/buildDeviceFeatures.ts +10 -5
  182. package/src/events/logBlockEvent.ts +14 -1
  183. package/src/events/ui-request.ts +3 -0
  184. package/src/index.ts +0 -10
  185. package/src/protocols/protocol-v2/features.ts +22 -5
  186. package/src/protocols/protocol-v2/index.ts +2 -0
  187. package/src/protocols/protocol-v2/resources.ts +110 -147
  188. package/src/protocols/protocol-v2/unlockPolicyRunner.ts +13 -1
  189. package/src/protocols/protocol-v2/walletSession.ts +65 -22
  190. package/src/types/api/firmwareUpdate.ts +1 -1
  191. package/src/types/api/firmwareUpdatePlan.ts +2 -2
  192. package/src/types/api/protocolV2.ts +1 -1
  193. package/src/types/device.ts +2 -1
  194. package/src/types/settings.ts +6 -34
  195. package/src/utils/deviceFeaturesCompat.ts +9 -4
  196. package/src/utils/deviceFeaturesUtils.ts +4 -0
  197. package/src/utils/deviceInfoUtils.ts +9 -2
  198. package/src/utils/deviceSettings.ts +11 -4
  199. package/src/utils/index.ts +1 -0
  200. package/src/utils/pro2Nft.ts +31 -8
  201. package/__tests__/firmware-memory-host.test.ts +0 -112
  202. package/dist/api/firmware/FirmwareMemoryHost.d.ts +0 -22
  203. package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +0 -1
  204. package/src/api/firmware/FirmwareMemoryHost.ts +0 -142
@@ -1,14 +1,6 @@
1
1
  import { BaseMethod } from '../BaseMethod';
2
- import {
3
- PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS,
4
- PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES,
5
- isProtocolV2DeviceDisconnectedError,
6
- normalizeFirmwareTargets,
7
- } from './helpers';
8
- import { UI_REQUEST, createUiMessage } from '../../events/ui-request';
2
+ import { isProtocolV2DeviceDisconnectedError, normalizeFirmwareTargets } from './helpers';
9
3
 
10
- import type { KnownDevice } from '../../types';
11
- import type { MessageFromOneKey } from '@onekeyfe/hd-transport';
12
4
  import type { DeviceFirmwareUpdateParams } from './helpers';
13
5
 
14
6
  export default class DeviceFirmwareUpdate extends BaseMethod<DeviceFirmwareUpdateParams> {
@@ -31,27 +23,13 @@ export default class DeviceFirmwareUpdate extends BaseMethod<DeviceFirmwareUpdat
31
23
  async run() {
32
24
  const targets = normalizeFirmwareTargets(this.params);
33
25
  try {
34
- const res = await this.device.commands.typedCall(
26
+ await this.device.commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
27
+ await this.device.commands.call(
35
28
  'DeviceFirmwareUpdateRequest',
36
- PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES,
37
- {
38
- targets,
39
- },
40
- {
41
- ...PROTOCOL_V2_FIRMWARE_UPDATE_OPTIONS,
42
- onIntermediateResponse: (response: MessageFromOneKey) => {
43
- if (response.type !== 'DeviceFirmwareUpdateStatus') return;
44
- this.postMessage(
45
- createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
46
- device: this.device.toMessageObject() as KnownDevice,
47
- progress: 99,
48
- progressType: 'installingFirmware',
49
- })
50
- );
51
- },
52
- }
29
+ {},
30
+ { returnAfterWrite: true }
53
31
  );
54
- return res.message;
32
+ return { message: 'Device firmware update started' };
55
33
  } catch (error) {
56
34
  if (isProtocolV2DeviceDisconnectedError(error)) {
57
35
  return {
@@ -4,7 +4,13 @@ import { invalidParameter } from '../helpers/filesystemValidation';
4
4
  import type { DeviceFirmwareUpdateStatusGetParams } from './helpers';
5
5
  import type { DeviceFirmwareUpdateRecordFields } from '@onekeyfe/hd-transport';
6
6
 
7
- const DEVICE_FIRMWARE_UPDATE_STATUS_FIELDS = ['status', 'payload_version', 'path'] as const;
7
+ const DEVICE_FIRMWARE_UPDATE_STATUS_FIELDS = [
8
+ 'status',
9
+ 'progress_percent',
10
+ 'phase_info',
11
+ 'payload_version',
12
+ 'path',
13
+ ] as const;
8
14
 
9
15
  function normalizeStatusFields(
10
16
  fields: DeviceFirmwareUpdateStatusGetParams['fields']
@@ -5,7 +5,7 @@ import { invalidParameter } from '../helpers/filesystemValidation';
5
5
 
6
6
  export type DeviceInfoGetTargets = {
7
7
  hw?: boolean;
8
- fw?: boolean;
8
+ main_mcu?: boolean;
9
9
  coprocessor?: boolean;
10
10
  se1?: boolean;
11
11
  se2?: boolean;
@@ -27,7 +27,7 @@ export type DeviceInfoGetParams = {
27
27
 
28
28
  const TARGET_KEYS: (keyof DeviceInfoGetTargets)[] = [
29
29
  'hw',
30
- 'fw',
30
+ 'main_mcu',
31
31
  'coprocessor',
32
32
  'se1',
33
33
  'se2',
@@ -39,7 +39,7 @@ const TYPE_KEYS: (keyof DeviceInfoGetTypes)[] = ['version', 'build_id', 'hash',
39
39
 
40
40
  const DEFAULT_TARGETS: DeviceInfoGetTargets = {
41
41
  hw: true,
42
- fw: true,
42
+ main_mcu: true,
43
43
  coprocessor: true,
44
44
  };
45
45
 
@@ -1,3 +1,5 @@
1
+ import { DeviceSessionPinType } from '@onekeyfe/hd-transport';
2
+
1
3
  import { BaseMethod } from '../BaseMethod';
2
4
  import { normalizeRebootType } from './helpers';
3
5
 
@@ -11,6 +13,9 @@ export default class DeviceReboot extends BaseMethod<DeviceRebootParams> {
11
13
  init() {
12
14
  this.skipForceUpdateCheck = true;
13
15
  this.useDevicePassphraseState = false;
16
+ this.unlockPolicy = 'unlock-before-run';
17
+ // Device-management action: main PIN or Attach PIN may authorize reboot.
18
+ this.protocolV2PreUnlockPinType = DeviceSessionPinType.Any;
14
19
  this.params = {
15
20
  rebootType: this.payload.rebootType,
16
21
  reboot_type: this.payload.reboot_type,
@@ -1,4 +1,5 @@
1
1
  import { ERRORS, HardwareErrorCode, createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
2
+ import { DeviceSessionPinType } from '@onekeyfe/hd-transport';
2
3
 
3
4
  import { UI_REQUEST, createUiMessage } from '../../events/ui-request';
4
5
  import { supportsProtocolV2Message } from '../../protocols/protocol-v2/features';
@@ -7,21 +8,26 @@ import {
7
8
  PRO2_NFT_DEFAULT_PACE_MS,
8
9
  PRO2_NFT_DEFAULT_TIMEOUT_MS,
9
10
  PRO2_NFT_DIRECTORY,
11
+ PRO2_NFT_IMAGE_HEIGHT,
12
+ PRO2_NFT_IMAGE_WIDTH,
10
13
  PRO2_NFT_MAX_CHUNK_SIZE,
11
14
  PRO2_NFT_MAX_ITEMS,
12
15
  PRO2_NFT_MIN_CHUNK_SIZE,
16
+ PRO2_NFT_THUMBNAIL_HEIGHT,
17
+ PRO2_NFT_THUMBNAIL_WIDTH,
13
18
  type Pro2NftBundle,
14
- type Pro2NftImage,
15
- buildPro2NftBundle,
19
+ buildPro2NftBundleFromEncodedImages,
16
20
  getCompletePro2NftBasenames,
17
21
  } from '../../utils/pro2Nft';
22
+ import { encodePro2Image } from '../../utils/pro2Wallpaper';
18
23
  import { BaseMethod } from '../BaseMethod';
24
+ import { decodeJpegBase64ToRgba } from '../helpers/base64Data';
19
25
  import { invalidParameter } from '../helpers/filesystemValidation';
20
26
  import { writeProtocolV2File } from '../helpers/protocolV2FileWrite';
21
27
 
22
28
  export type DeviceUploadNftParams = {
23
- image: Pro2NftImage;
24
- thumbnail: Pro2NftImage;
29
+ imageJpegBase64: string;
30
+ thumbnailJpegBase64: string;
25
31
  title: string;
26
32
  subtitle: string;
27
33
  timestampMs?: number;
@@ -54,8 +60,8 @@ export default class DeviceUploadNft extends BaseMethod<DeviceUploadNftParams> {
54
60
 
55
61
  init() {
56
62
  const {
57
- image,
58
- thumbnail,
63
+ imageJpegBase64,
64
+ thumbnailJpegBase64,
59
65
  title,
60
66
  subtitle,
61
67
  timestampMs = Date.now(),
@@ -79,9 +85,55 @@ export default class DeviceUploadNft extends BaseMethod<DeviceUploadNftParams> {
79
85
  throw invalidParameter('Parameter [timeoutMs] must be a positive integer.');
80
86
  }
81
87
 
82
- this.bundle = buildPro2NftBundle({ image, thumbnail, title, subtitle, timestampMs });
83
- this.params = { image, thumbnail, title, subtitle, timestampMs, chunkSize, paceMs, timeoutMs };
84
- this.unlockPolicy = 'none';
88
+ const encodedImage = (() => {
89
+ const decoded = decodeJpegBase64ToRgba({
90
+ jpegBase64: imageJpegBase64,
91
+ parameterName: 'imageJpegBase64',
92
+ expectedWidth: PRO2_NFT_IMAGE_WIDTH,
93
+ expectedHeight: PRO2_NFT_IMAGE_HEIGHT,
94
+ });
95
+ return encodePro2Image({
96
+ width: PRO2_NFT_IMAGE_WIDTH,
97
+ height: PRO2_NFT_IMAGE_HEIGHT,
98
+ rgba: decoded.data,
99
+ alphaMode: 'black-background',
100
+ }).data;
101
+ })();
102
+ const encodedThumbnail = (() => {
103
+ const decoded = decodeJpegBase64ToRgba({
104
+ jpegBase64: thumbnailJpegBase64,
105
+ parameterName: 'thumbnailJpegBase64',
106
+ expectedWidth: PRO2_NFT_THUMBNAIL_WIDTH,
107
+ expectedHeight: PRO2_NFT_THUMBNAIL_HEIGHT,
108
+ });
109
+ return encodePro2Image({
110
+ width: PRO2_NFT_THUMBNAIL_WIDTH,
111
+ height: PRO2_NFT_THUMBNAIL_HEIGHT,
112
+ rgba: decoded.data,
113
+ alphaMode: 'black-background',
114
+ }).data;
115
+ })();
116
+ this.bundle = buildPro2NftBundleFromEncodedImages({
117
+ image: encodedImage,
118
+ thumbnail: encodedThumbnail,
119
+ title,
120
+ subtitle,
121
+ timestampMs,
122
+ });
123
+ this.params = {
124
+ imageJpegBase64,
125
+ thumbnailJpegBase64,
126
+ title,
127
+ subtitle,
128
+ timestampMs,
129
+ chunkSize,
130
+ paceMs,
131
+ timeoutMs,
132
+ };
133
+ this.unlockPolicy = 'unlock-before-run';
134
+ // File writes and NftUpdate require an unlocked device. Either PIN may
135
+ // authorize this device-management action.
136
+ this.protocolV2PreUnlockPinType = DeviceSessionPinType.Any;
85
137
  this.skipForceUpdateCheck = true;
86
138
  this.useDevicePassphraseState = false;
87
139
  }
@@ -1,10 +1,15 @@
1
1
  import { blake2s } from '@noble/hashes/blake2s';
2
2
  import { bytesToHex } from '@noble/hashes/utils';
3
+ import { createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
4
+ import { DeviceSessionPinType } from '@onekeyfe/hd-transport';
3
5
 
4
6
  import { BaseMethod } from '../BaseMethod';
7
+ import { decodeJpegBase64ToRgba } from '../helpers/base64Data';
5
8
  import { invalidParameter } from '../helpers/filesystemValidation';
6
9
  import { writeProtocolV2File } from '../helpers/protocolV2FileWrite';
7
10
  import { UI_REQUEST, createUiMessage } from '../../events/ui-request';
11
+ import { supportsProtocolV2Message } from '../../protocols/protocol-v2/features';
12
+ import { LoggerNames, getLogger } from '../../utils';
8
13
  import {
9
14
  PRO2_WALLPAPER_HEIGHT,
10
15
  PRO2_WALLPAPER_WIDTH,
@@ -13,9 +18,7 @@ import {
13
18
  } from '../../utils/pro2Wallpaper';
14
19
 
15
20
  export type DeviceUploadWallpaperParams = {
16
- width: number;
17
- height: number;
18
- rgba: Uint8Array | ArrayBuffer;
21
+ jpegBase64: string;
19
22
  fileName?: string;
20
23
  chunkSize?: number;
21
24
  };
@@ -29,6 +32,10 @@ export type DeviceUploadWallpaperResponse = {
29
32
 
30
33
  const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
31
34
  const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
35
+ const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
36
+ const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
37
+ const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
38
+ const Log = getLogger(LoggerNames.Method);
32
39
 
33
40
  function normalizeFileName(fileName: string | undefined, data: Uint8Array): string {
34
41
  if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
@@ -54,31 +61,48 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
54
61
  private path = '';
55
62
 
56
63
  init() {
57
- const { width, height, rgba, fileName, chunkSize } = this.payload;
58
- if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
59
- throw invalidParameter(
60
- `Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`
61
- );
62
- }
63
- if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
64
- throw invalidParameter('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
65
- }
64
+ const { jpegBase64, fileName, chunkSize } = this.payload;
66
65
  if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
67
66
  throw invalidParameter('Parameter [chunkSize] must be a positive integer.');
68
67
  }
69
68
 
70
- const rgbaBytes =
71
- rgba instanceof ArrayBuffer
72
- ? rgba
73
- : new Uint8Array(rgba.buffer, rgba.byteOffset, rgba.byteLength);
74
- this.encoded = encodePro2Wallpaper({ width, height, rgba: rgbaBytes });
69
+ const decoded = decodeJpegBase64ToRgba({
70
+ jpegBase64,
71
+ parameterName: 'jpegBase64',
72
+ expectedWidth: PRO2_WALLPAPER_WIDTH,
73
+ expectedHeight: PRO2_WALLPAPER_HEIGHT,
74
+ });
75
+ this.encoded = encodePro2Wallpaper({
76
+ width: PRO2_WALLPAPER_WIDTH,
77
+ height: PRO2_WALLPAPER_HEIGHT,
78
+ rgba: decoded.data,
79
+ });
75
80
  this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
76
- this.params = { width, height, rgba: rgbaBytes, fileName, chunkSize };
77
- this.unlockPolicy = 'none';
81
+ this.params = { jpegBase64, fileName, chunkSize };
82
+ this.unlockPolicy = 'unlock-before-run';
83
+ // File writes and wallpaper apply require an unlocked device. Either PIN
84
+ // may authorize this device-management action.
85
+ this.protocolV2PreUnlockPinType = DeviceSessionPinType.Any;
78
86
  this.skipForceUpdateCheck = true;
79
87
  this.useDevicePassphraseState = false;
80
88
  }
81
89
 
90
+ private async assertCapabilities() {
91
+ const protocolInfo = await this.device.ensureProtocolV2RuntimeContext();
92
+ const requiredMessageTypes = [
93
+ DEVICE_SETTINGS_SET_MESSAGE_TYPE,
94
+ FILESYSTEM_FILE_WRITE_MESSAGE_TYPE,
95
+ FILESYSTEM_DIR_MAKE_MESSAGE_TYPE,
96
+ ];
97
+ if (
98
+ requiredMessageTypes.some(
99
+ messageType => !supportsProtocolV2Message(protocolInfo, messageType)
100
+ )
101
+ ) {
102
+ throw createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
103
+ }
104
+ }
105
+
82
106
  private async ensureDirectory() {
83
107
  if (this.directoryReady) return;
84
108
  try {
@@ -119,11 +143,21 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
119
143
  async run(): Promise<DeviceUploadWallpaperResponse> {
120
144
  const { encoded } = this;
121
145
  if (!encoded) throw invalidParameter('Wallpaper data has not been initialized.');
146
+ await this.assertCapabilities();
122
147
  await this.ensureDirectory();
123
148
  await this.upload();
124
149
  const response = await this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
125
150
  settings: { wallpaper_path: this.path },
126
151
  });
152
+ try {
153
+ await this.device.refreshProtocolV2SettingsAfterMutation();
154
+ } catch (error) {
155
+ // The wallpaper is already applied. A transient read-back failure must not
156
+ // make callers retry the completed file upload.
157
+ Log.warn('Protocol V2 wallpaper settings refresh failed after apply', {
158
+ error: error instanceof Error ? error.message : String(error),
159
+ });
160
+ }
127
161
  return {
128
162
  path: this.path,
129
163
  size: encoded.data.byteLength,
@@ -1,4 +1,5 @@
1
1
  import { DeviceRebootType } from '@onekeyfe/hd-transport';
2
+ import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
3
 
3
4
  import { invalidParameter, validateNonEmptyString } from '../helpers/filesystemValidation';
4
5
  import { ProtocolV2FirmwareTargetType } from '../../protocols/protocol-v2/firmware';
@@ -103,6 +104,13 @@ export const getProtocolV2UnknownErrorText = (error: unknown) => {
103
104
  };
104
105
 
105
106
  export const isProtocolV2DeviceDisconnectedError = (error: unknown) => {
107
+ const errorCode =
108
+ error && typeof error === 'object'
109
+ ? (error as { errorCode?: number; code?: number }).errorCode ??
110
+ (error as { errorCode?: number; code?: number }).code
111
+ : undefined;
112
+ if (errorCode === HardwareErrorCode.BleDeviceDisconnected) return true;
113
+
106
114
  const message = getProtocolV2UnknownErrorText(error).toLowerCase();
107
115
  const compactMessage = message.replace(/\s+/g, '');
108
116
  return (
@@ -174,12 +174,14 @@ export default class TonSignMessage extends BaseMethod<HardwareTonSignMessage> {
174
174
  if (!request.init_data_length) {
175
175
  const deviceType = this.device.getCurrentDeviceType();
176
176
  const hasClassic = DeviceModelToTypes.model_classic1s.includes(deviceType);
177
- // use signing_message_repr sign, not exists signning_message, skip validate
178
- const hasSigningMessageRepr = request.signning_message == null;
177
+ const signingMessage = request.signing_message ?? request.signning_message;
178
+ // Blind signing omits the signing message in both protocol schemas.
179
+ const shouldSkipValidation = signingMessage == null;
179
180
 
180
181
  return Promise.resolve({
181
182
  ...request,
182
- skip_validate: hasClassic || hasSigningMessageRepr,
183
+ signing_message: signingMessage,
184
+ skip_validate: hasClassic || shouldSkipValidation,
183
185
  });
184
186
  }
185
187