@onekeyfe/hd-core 1.2.0-alpha.16 → 1.2.0-alpha.18

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 (125) hide show
  1. package/__tests__/DeviceEventRegistration.test.ts +3 -0
  2. package/__tests__/deviceFeaturesUtils.test.ts +27 -0
  3. package/__tests__/evmLedgerLegacySafety.test.ts +3 -0
  4. package/__tests__/homescreen.test.ts +24 -0
  5. package/__tests__/kaspaSignTransaction.test.ts +591 -0
  6. package/__tests__/protocol-v2.test.ts +1006 -204
  7. package/__tests__/protocolV2FileWrite.test.ts +28 -3
  8. package/__tests__/protocolV2UiInteraction.test.ts +266 -0
  9. package/dist/api/BaseMethod.d.ts +4 -0
  10. package/dist/api/BaseMethod.d.ts.map +1 -1
  11. package/dist/api/FirmwareUpdateV4.d.ts +3 -3
  12. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  13. package/dist/api/GetDeviceInfo.d.ts.map +1 -1
  14. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  15. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  16. package/dist/api/device/DeviceCancel.d.ts.map +1 -1
  17. package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
  18. package/dist/api/device/DeviceLock.d.ts.map +1 -1
  19. package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
  20. package/dist/api/device/DeviceWipe.d.ts.map +1 -1
  21. package/dist/api/helpers/protocolV2FileWrite.d.ts +1 -0
  22. package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
  23. package/dist/api/index.d.ts +1 -1
  24. package/dist/api/index.d.ts.map +1 -1
  25. package/dist/api/kaspa/KaspaSignTransaction.d.ts +5 -1
  26. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  27. package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -1
  28. package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
  29. package/dist/api/protocol-v2/DeviceSessionOpen.d.ts +28 -0
  30. package/dist/api/protocol-v2/DeviceSessionOpen.d.ts.map +1 -0
  31. package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +1 -1
  32. package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +1 -1
  33. package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -1
  34. package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
  35. package/dist/core/deviceEventRegistration.d.ts +1 -0
  36. package/dist/core/deviceEventRegistration.d.ts.map +1 -1
  37. package/dist/core/index.d.ts.map +1 -1
  38. package/dist/device/Device.d.ts +3 -3
  39. package/dist/device/Device.d.ts.map +1 -1
  40. package/dist/device/DeviceCommands.d.ts +7 -5
  41. package/dist/device/DeviceCommands.d.ts.map +1 -1
  42. package/dist/device/DevicePool.d.ts +2 -2
  43. package/dist/device/DevicePool.d.ts.map +1 -1
  44. package/dist/deviceProfile/buildDeviceFeatures.d.ts +6 -2
  45. package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
  46. package/dist/deviceProfile/buildDeviceProfile.d.ts +3 -2
  47. package/dist/deviceProfile/buildDeviceProfile.d.ts.map +1 -1
  48. package/dist/events/device.d.ts +4 -0
  49. package/dist/events/device.d.ts.map +1 -1
  50. package/dist/events/ui-request.d.ts +18 -2
  51. package/dist/events/ui-request.d.ts.map +1 -1
  52. package/dist/index.d.ts +85 -15
  53. package/dist/index.js +1515 -554
  54. package/dist/protocols/protocol-v2/features.d.ts +6 -18
  55. package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
  56. package/dist/protocols/protocol-v2/index.d.ts +1 -1
  57. package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
  58. package/dist/protocols/protocol-v2/uiInteraction.d.ts +39 -0
  59. package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
  60. package/dist/protocols/protocol-v2/unlockRetry.d.ts +5 -3
  61. package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -1
  62. package/dist/protocols/protocol-v2/walletSession.d.ts +2 -1
  63. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  64. package/dist/types/api/getDeviceInfo.d.ts +2 -1
  65. package/dist/types/api/getDeviceInfo.d.ts.map +1 -1
  66. package/dist/types/api/index.d.ts +2 -2
  67. package/dist/types/api/index.d.ts.map +1 -1
  68. package/dist/types/api/kaspaSignTransaction.d.ts +27 -2
  69. package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
  70. package/dist/types/api/protocolV2.d.ts +4 -2
  71. package/dist/types/api/protocolV2.d.ts.map +1 -1
  72. package/dist/types/device.d.ts +2 -1
  73. package/dist/types/device.d.ts.map +1 -1
  74. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  75. package/dist/utils/homescreen.d.ts.map +1 -1
  76. package/dist/utils/patch.d.ts +1 -1
  77. package/dist/utils/patch.d.ts.map +1 -1
  78. package/package.json +4 -4
  79. package/src/api/BaseMethod.ts +10 -2
  80. package/src/api/FirmwareUpdateV4.ts +27 -73
  81. package/src/api/GetDeviceInfo.ts +9 -2
  82. package/src/api/GetPassphraseState.ts +5 -2
  83. package/src/api/UploadPortfolio.ts +2 -0
  84. package/src/api/device/DeviceCancel.ts +1 -0
  85. package/src/api/device/DeviceChangePin.ts +23 -0
  86. package/src/api/device/DeviceLock.ts +1 -0
  87. package/src/api/device/DeviceUnlock.ts +9 -0
  88. package/src/api/device/DeviceWipe.ts +18 -0
  89. package/src/api/helpers/protocolV2FileWrite.ts +35 -11
  90. package/src/api/index.ts +1 -1
  91. package/src/api/kaspa/KaspaSignTransaction.ts +341 -22
  92. package/src/api/kaspa/helpers/TransferSerialize.ts +14 -0
  93. package/src/api/protocol-v2/DeviceInfoGet.ts +0 -1
  94. package/src/api/protocol-v2/DeviceSessionOpen.ts +100 -0
  95. package/src/api/protocol-v2/DeviceSettingsPageShow.ts +9 -1
  96. package/src/api/protocol-v2/DeviceSettingsSet.ts +11 -1
  97. package/src/api/protocol-v2/DeviceStatusGet.ts +1 -0
  98. package/src/api/protocol-v2/DeviceUploadWallpaper.ts +2 -1
  99. package/src/core/deviceEventRegistration.ts +2 -0
  100. package/src/core/index.ts +36 -3
  101. package/src/data/messages/messages-protocol-v2.json +122 -23
  102. package/src/data/messages/messages.json +286 -1
  103. package/src/device/Device.ts +33 -41
  104. package/src/device/DeviceCommands.ts +22 -4
  105. package/src/device/DevicePool.ts +14 -6
  106. package/src/deviceProfile/buildDeviceFeatures.ts +21 -9
  107. package/src/deviceProfile/buildDeviceProfile.ts +27 -11
  108. package/src/events/device.ts +4 -0
  109. package/src/events/ui-request.ts +24 -2
  110. package/src/inject.ts +2 -2
  111. package/src/protocols/protocol-v2/features.ts +27 -20
  112. package/src/protocols/protocol-v2/index.ts +0 -1
  113. package/src/protocols/protocol-v2/uiInteraction.ts +209 -0
  114. package/src/protocols/protocol-v2/unlockRetry.ts +43 -3
  115. package/src/protocols/protocol-v2/walletSession.ts +122 -31
  116. package/src/types/api/getDeviceInfo.ts +6 -1
  117. package/src/types/api/index.ts +2 -2
  118. package/src/types/api/kaspaSignTransaction.ts +40 -2
  119. package/src/types/api/protocolV2.ts +5 -3
  120. package/src/types/device.ts +6 -1
  121. package/src/utils/deviceFeaturesUtils.ts +13 -0
  122. package/src/utils/homescreen.ts +10 -0
  123. package/dist/api/protocol-v2/DeviceSessionGet.d.ts +0 -6
  124. package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +0 -1
  125. package/src/api/protocol-v2/DeviceSessionGet.ts +0 -15
@@ -1,4 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+ import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
3
+
2
4
  import { SignatureType } from './SignatureType';
3
5
  import { HashWriter } from './HashWriter';
4
6
 
@@ -76,6 +78,12 @@ function getSigOpCountsHash(transaction: KaspaSignTransactionParams, sighashType
76
78
  function hashTxOut(hashWriter: HashWriter, output: KaspaSignOutputParams) {
77
79
  hashWriter.writeUInt64LE(output.satoshis);
78
80
  hashWriter.writeUInt16LE(0); // TODO: USE REAL SCRIPT VERSION
81
+ if (output.script === undefined) {
82
+ throw ERRORS.TypedError(
83
+ HardwareErrorCode.CallMethodInvalidParameter,
84
+ 'Kaspa legacy sighash requires output.script'
85
+ );
86
+ }
79
87
  hashWriter.writeVarBytes(Buffer.from(output.script, 'hex'));
80
88
  }
81
89
 
@@ -126,6 +134,12 @@ export function serialize(transaction: KaspaSignTransactionParams, inputNumber:
126
134
  const input = transaction.inputs[inputNumber];
127
135
  hashOutpoint(hashWriter, input);
128
136
  hashWriter.writeUInt16LE(0); // TODO: USE REAL SCRIPT VERSION
137
+ if (input.output.script === undefined) {
138
+ throw ERRORS.TypedError(
139
+ HardwareErrorCode.CallMethodInvalidParameter,
140
+ 'Kaspa legacy sighash requires input.output.script'
141
+ );
142
+ }
129
143
  hashWriter.writeVarBytes(Buffer.from(input.output.script, 'hex'));
130
144
  hashWriter.writeUInt64LE(input.output.satoshis);
131
145
  hashWriter.writeUInt64LE(input.sequenceNumber);
@@ -45,7 +45,6 @@ const DEFAULT_TARGETS: DeviceInfoGetTargets = {
45
45
  hw: true,
46
46
  fw: true,
47
47
  coprocessor: true,
48
- status: true,
49
48
  };
50
49
 
51
50
  const DEFAULT_TYPES: DeviceInfoGetTypes = {
@@ -0,0 +1,100 @@
1
+ import { BaseMethod } from '../BaseMethod';
2
+ import { invalidParameter } from '../helpers/filesystemValidation';
3
+
4
+ import type {
5
+ DeviceAttachPinOnDevice,
6
+ DeviceHostPassphrase,
7
+ DevicePassphraseOnDevice,
8
+ DeviceSessionResume,
9
+ } from '@onekeyfe/hd-transport';
10
+
11
+ type HiddenWalletSelection =
12
+ | {
13
+ host_passphrase: DeviceHostPassphrase;
14
+ passphrase_on_device?: never;
15
+ attach_pin_on_device?: never;
16
+ }
17
+ | {
18
+ host_passphrase?: never;
19
+ passphrase_on_device: DevicePassphraseOnDevice;
20
+ attach_pin_on_device?: never;
21
+ }
22
+ | {
23
+ host_passphrase?: never;
24
+ passphrase_on_device?: never;
25
+ attach_pin_on_device: DeviceAttachPinOnDevice;
26
+ };
27
+
28
+ export type DeviceSessionOpenParams =
29
+ | { resume: DeviceSessionResume; select?: never }
30
+ | { resume?: never; select: HiddenWalletSelection };
31
+
32
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
33
+ !!value && typeof value === 'object' && !Array.isArray(value);
34
+
35
+ const normalizeParams = (payload: Record<string, unknown>): DeviceSessionOpenParams => {
36
+ const hasResume = payload.resume !== undefined;
37
+ const hasSelect = payload.select !== undefined;
38
+ if (hasResume === hasSelect) {
39
+ throw invalidParameter('DeviceSessionOpen requires exactly one of [resume] or [select].');
40
+ }
41
+
42
+ if (hasResume) {
43
+ if (!isRecord(payload.resume) || typeof payload.resume.session_id !== 'string') {
44
+ throw invalidParameter('Parameter [resume.session_id] must be a non-empty string.');
45
+ }
46
+ const sessionId = payload.resume.session_id.trim();
47
+ if (!sessionId) {
48
+ throw invalidParameter('Parameter [resume.session_id] must be a non-empty string.');
49
+ }
50
+ return { resume: { session_id: sessionId } };
51
+ }
52
+
53
+ if (!isRecord(payload.select)) {
54
+ throw invalidParameter('Parameter [select] must be a hidden-wallet selection object.');
55
+ }
56
+ const { select } = payload;
57
+ const accessKeys = ['host_passphrase', 'passphrase_on_device', 'attach_pin_on_device'] as const;
58
+ const selected = accessKeys.filter(key => select[key] !== undefined);
59
+ const unknown = Object.keys(select).filter(
60
+ key => !accessKeys.includes(key as (typeof accessKeys)[number])
61
+ );
62
+ if (unknown.length > 0 || selected.length !== 1) {
63
+ throw invalidParameter('Parameter [select] requires exactly one hidden-wallet access mode.');
64
+ }
65
+
66
+ if (selected[0] === 'host_passphrase') {
67
+ const host = select.host_passphrase;
68
+ if (!isRecord(host) || typeof host.passphrase !== 'string') {
69
+ throw invalidParameter('Parameter [select.host_passphrase.passphrase] is required.');
70
+ }
71
+ const passphrase = host.passphrase.normalize('NFKD');
72
+ if (!passphrase || passphrase.includes('\0') || passphrase.length > 50) {
73
+ throw invalidParameter('Parameter [select.host_passphrase.passphrase] is invalid.');
74
+ }
75
+ return { select: { host_passphrase: { passphrase } } };
76
+ }
77
+
78
+ if (selected[0] === 'passphrase_on_device') {
79
+ return { select: { passphrase_on_device: {} } };
80
+ }
81
+ return { select: { attach_pin_on_device: {} } };
82
+ };
83
+
84
+ export default class DeviceSessionOpen extends BaseMethod<DeviceSessionOpenParams> {
85
+ init() {
86
+ this.requireProtocolV2 = true;
87
+ this.useDevicePassphraseState = false;
88
+ this.skipForceUpdateCheck = true;
89
+ this.params = normalizeParams(this.payload as unknown as Record<string, unknown>);
90
+ }
91
+
92
+ async run() {
93
+ const { message } = await this.device.commands.typedCall(
94
+ 'DeviceSessionOpen',
95
+ 'DeviceSession',
96
+ this.params
97
+ );
98
+ return message;
99
+ }
100
+ }
@@ -26,7 +26,7 @@ const SUPPORTED_PAGES = new Set<number>([
26
26
  function normalizePage(value: DeviceSettingsPageShowParams['page']): SupportedDeviceSettingsPage {
27
27
  const page = typeof value === 'string' ? DeviceSettingsPage[value] : value;
28
28
  if (page !== undefined && SUPPORTED_PAGES.has(page)) {
29
- return page as SupportedDeviceSettingsPage;
29
+ return page;
30
30
  }
31
31
  throw invalidParameter(
32
32
  'Parameter [page] must be DeviceReset, DevicePinChange, DevicePassphrase, or DeviceAirgap.'
@@ -46,6 +46,14 @@ export default class DeviceSettingsPageShow extends BaseMethod<{
46
46
  page: normalizePage(this.payload.page),
47
47
  field_name: this.payload.field_name ?? this.payload.fieldName,
48
48
  };
49
+ this.protocolV2UiInteraction = {
50
+ request: 'button',
51
+ source: 'method-lifecycle',
52
+ reason: 'settings-page',
53
+ completion: 'operation-completed',
54
+ deviceOnly: true,
55
+ page: this.params.page,
56
+ };
49
57
  }
50
58
 
51
59
  async run() {
@@ -11,7 +11,7 @@ export default class DeviceSettingsSet extends BaseMethod<{
11
11
  settings: Omit<DeviceSettings, 'passphrase_enable' | 'airgap_mode'>;
12
12
  }> {
13
13
  init() {
14
- const settings = this.payload.settings;
14
+ const { settings } = this.payload;
15
15
  if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
16
16
  throw invalidParameter('Parameter [settings] must be an object.');
17
17
  }
@@ -30,6 +30,16 @@ export default class DeviceSettingsSet extends BaseMethod<{
30
30
  this.skipForceUpdateCheck = true;
31
31
  this.useDevicePassphraseState = false;
32
32
  this.params = { settings: supported };
33
+ if (typeof supported.label === 'string') {
34
+ this.protocolV2UiInteraction = {
35
+ request: 'button',
36
+ source: 'method-lifecycle',
37
+ reason: 'device-management',
38
+ completion: 'operation-completed',
39
+ deviceOnly: true,
40
+ operation: 'change-label',
41
+ };
42
+ }
33
43
  }
34
44
 
35
45
  async run() {
@@ -9,6 +9,7 @@ export default class DeviceStatusGet extends BaseMethod {
9
9
 
10
10
  async run() {
11
11
  const { message } = await this.device.commands.typedCall('DeviceStatusGet', 'DeviceStatus', {});
12
+ this.device.updateProtocolV2Status(message);
12
13
  return message;
13
14
  }
14
15
  }
@@ -27,7 +27,7 @@ export type DeviceUploadWallpaperResponse = {
27
27
  message?: string;
28
28
  };
29
29
 
30
- const WALLPAPER_DIRECTORY = 'vol0:/wallpapers/user';
30
+ const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
31
31
  const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
32
32
 
33
33
  function normalizeFileName(fileName: string | undefined, data: Uint8Array): string {
@@ -100,6 +100,7 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
100
100
  data: encoded.data,
101
101
  totalSize: encoded.data.byteLength,
102
102
  chunkSize: this.params.chunkSize,
103
+ maxChunkRetries: 3,
103
104
  overwrite: true,
104
105
  append: false,
105
106
  throwIfAborted: () => this.throwIfAborted(),
@@ -7,6 +7,7 @@ export type HardwareUiEventHandlers = {
7
7
  button: (...event: DeviceEvents[typeof DEVICE.BUTTON]) => void;
8
8
  passphrase: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE]) => void;
9
9
  passphraseOnDevice: (...event: DeviceEvents[typeof DEVICE.PASSPHRASE_ON_DEVICE]) => void;
10
+ attachPinOnDevice: (...event: DeviceEvents[typeof DEVICE.ATTACH_PIN_ON_DEVICE]) => void;
10
11
  };
11
12
 
12
13
  export function registerHardwareUiEventListeners(
@@ -17,5 +18,6 @@ export function registerHardwareUiEventListeners(
17
18
  device.on(DEVICE.BUTTON, handlers.button);
18
19
  device.on(DEVICE.PASSPHRASE, handlers.passphrase);
19
20
  device.on(DEVICE.PASSPHRASE_ON_DEVICE, handlers.passphraseOnDevice);
21
+ device.on(DEVICE.ATTACH_PIN_ON_DEVICE, handlers.attachPinOnDevice);
20
22
  return true;
21
23
  }
package/src/core/index.ts CHANGED
@@ -58,6 +58,10 @@ import RequestQueue from './RequestQueue';
58
58
  import { registerHardwareUiEventListeners } from './deviceEventRegistration';
59
59
  import { getSynchronize } from '../utils/getSynchronize';
60
60
  import { runMethodWithUnlockRetry } from '../protocols/protocol-v2/unlockRetry';
61
+ import {
62
+ ProtocolV2UiInteractionCoordinator,
63
+ isProtocolV2UiEnabled,
64
+ } from '../protocols/protocol-v2/uiInteraction';
61
65
 
62
66
  import type { ConnectSettings, Features, KnownDevice } from '../types';
63
67
  import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
@@ -403,12 +407,15 @@ const onCallDevice = async (
403
407
  ? onEmptyPassphraseHandler
404
408
  : onDevicePassphraseHandler,
405
409
  passphraseOnDevice: onEnterPassphraseOnDeviceHandler,
410
+ attachPinOnDevice: onEnterAttachPinOnDeviceHandler,
406
411
  });
407
412
  device.on(DEVICE.FEATURES, onDeviceFeaturesHandler);
408
413
  device.on(
409
414
  DEVICE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE,
410
415
  onSelectDeviceInBootloaderForWebDeviceHandler
411
416
  );
417
+
418
+ const protocolV2UiCoordinator = new ProtocolV2UiInteractionCoordinator(device, postMessage);
412
419
  device.on(
413
420
  DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE,
414
421
  onSelectDeviceForSwitchFirmwareWebDeviceHandler
@@ -619,7 +626,11 @@ const onCallDevice = async (
619
626
  method.device?.commands?.checkDisposed();
620
627
 
621
628
  try {
622
- const response: object = await runMethodWithUnlockRetry(method, device);
629
+ const response: object = await runMethodWithUnlockRetry(
630
+ method,
631
+ device,
632
+ protocolV2UiCoordinator
633
+ );
623
634
  messageResponse = createResponseMessage(method.responseID, true, response);
624
635
  requestQueue.resolveRequest(method.responseID, messageResponse);
625
636
  completeMethodRequestContext(method);
@@ -636,6 +647,8 @@ const onCallDevice = async (
636
647
  ) {
637
648
  throw error;
638
649
  }
650
+ } finally {
651
+ protocolV2UiCoordinator.close();
639
652
  }
640
653
  };
641
654
  Log.debug('Call API - Device Run: ', device.mainId);
@@ -689,7 +702,9 @@ const onCallDevice = async (
689
702
 
690
703
  requestQueue.releaseTask(method.responseID);
691
704
 
692
- closePopup();
705
+ if (isProtocolV2UiEnabled(method)) {
706
+ closePopup();
707
+ }
693
708
 
694
709
  cleanup();
695
710
 
@@ -1235,6 +1250,9 @@ const onDevicePassphraseHandler = async (
1235
1250
  device: device.toMessageObject() as KnownDevice,
1236
1251
  passphraseState: device.passphraseState,
1237
1252
  existsAttachPinUser: requestPayload.existsAttachPinUser,
1253
+ source: requestPayload.source,
1254
+ reason: requestPayload.reason,
1255
+ expectedPassphraseState: requestPayload.expectedPassphraseState,
1238
1256
  })
1239
1257
  );
1240
1258
  // wait for passphrase
@@ -1256,12 +1274,27 @@ const onEmptyPassphraseHandler = (...[_, , callback]: DeviceEvents['passphrase']
1256
1274
  };
1257
1275
 
1258
1276
  const onEnterPassphraseOnDeviceHandler = (
1259
- ...[device]: [...DeviceEvents['passphrase_on_device']]
1277
+ ...[device, requestPayload]: [...DeviceEvents['passphrase_on_device']]
1260
1278
  ) => {
1261
1279
  postMessage(
1262
1280
  createUiMessage(UI_REQUEST.REQUEST_PASSPHRASE_ON_DEVICE, {
1263
1281
  device: device.toMessageObject() as KnownDevice,
1264
1282
  passphraseState: device.passphraseState,
1283
+ source: requestPayload?.source,
1284
+ reason: requestPayload?.reason,
1285
+ })
1286
+ );
1287
+ };
1288
+
1289
+ const onEnterAttachPinOnDeviceHandler = (
1290
+ ...[device, requestPayload]: [...DeviceEvents['attach_pin_on_device']]
1291
+ ) => {
1292
+ postMessage(
1293
+ createUiMessage(UI_REQUEST.REQUEST_PIN, {
1294
+ device: device.toMessageObject() as KnownDevice,
1295
+ type: 'ButtonRequest_AttachPin',
1296
+ source: requestPayload?.source,
1297
+ reason: requestPayload?.reason,
1265
1298
  })
1266
1299
  );
1267
1300
  };
@@ -482,7 +482,7 @@
482
482
  "MessageType_DeviceStatus": 60603,
483
483
  "MessageType_DevGetOnboardingStatus": 60604,
484
484
  "MessageType_DevOnboardingStatus": 60605,
485
- "MessageType_DeviceSessionGet": 60606,
485
+ "MessageType_DeviceSessionOpen": 60606,
486
486
  "MessageType_DeviceSession": 60607,
487
487
  "MessageType_DeviceSessionAskPin": 60608,
488
488
  "MessageType_FilesystemPermissionFix": 60800,
@@ -12418,14 +12418,68 @@
12418
12418
  }
12419
12419
  }
12420
12420
  },
12421
- "DeviceSessionGet": {
12421
+ "DeviceSessionResume": {
12422
12422
  "fields": {
12423
12423
  "session_id": {
12424
+ "rule": "required",
12424
12425
  "type": "bytes",
12425
12426
  "id": 1
12426
12427
  }
12427
12428
  }
12428
12429
  },
12430
+ "DeviceHostPassphrase": {
12431
+ "fields": {
12432
+ "passphrase": {
12433
+ "rule": "required",
12434
+ "type": "string",
12435
+ "id": 1
12436
+ }
12437
+ }
12438
+ },
12439
+ "DevicePassphraseOnDevice": {
12440
+ "fields": {}
12441
+ },
12442
+ "DeviceAttachPinOnDevice": {
12443
+ "fields": {}
12444
+ },
12445
+ "DeviceWalletSelect": {
12446
+ "oneofs": {
12447
+ "access": {
12448
+ "oneof": ["host_passphrase", "passphrase_on_device", "attach_pin_on_device"]
12449
+ }
12450
+ },
12451
+ "fields": {
12452
+ "host_passphrase": {
12453
+ "type": "DeviceHostPassphrase",
12454
+ "id": 1
12455
+ },
12456
+ "passphrase_on_device": {
12457
+ "type": "DevicePassphraseOnDevice",
12458
+ "id": 2
12459
+ },
12460
+ "attach_pin_on_device": {
12461
+ "type": "DeviceAttachPinOnDevice",
12462
+ "id": 3
12463
+ }
12464
+ }
12465
+ },
12466
+ "DeviceSessionOpen": {
12467
+ "oneofs": {
12468
+ "mode": {
12469
+ "oneof": ["resume", "select"]
12470
+ }
12471
+ },
12472
+ "fields": {
12473
+ "resume": {
12474
+ "type": "DeviceSessionResume",
12475
+ "id": 1
12476
+ },
12477
+ "select": {
12478
+ "type": "DeviceWalletSelect",
12479
+ "id": 2
12480
+ }
12481
+ }
12482
+ },
12429
12483
  "DeviceSession": {
12430
12484
  "fields": {
12431
12485
  "session_id": {
@@ -12481,21 +12535,59 @@
12481
12535
  "DeviceStatusGet": {
12482
12536
  "fields": {}
12483
12537
  },
12484
- "DevOnboardingStage": {
12538
+ "DevOnboardingStep": {
12539
+ "values": {
12540
+ "DEV_ONBOARDING_STEP_UNKNOWN": 0,
12541
+ "DEV_ONBOARDING_STEP_CHECKING": 1,
12542
+ "DEV_ONBOARDING_STEP_PERSONALIZATION": 2,
12543
+ "DEV_ONBOARDING_STEP_PIN": 3,
12544
+ "DEV_ONBOARDING_STEP_SETUP": 4,
12545
+ "DEV_ONBOARDING_STEP_DONE": 5
12546
+ }
12547
+ },
12548
+ "DevOnboardingPhase": {
12549
+ "values": {
12550
+ "DEV_ONBOARDING_PHASE_UNKNOWN": 0,
12551
+ "DEV_ONBOARDING_PHASE_SAFETY_CHECK": 1,
12552
+ "DEV_ONBOARDING_PHASE_PIN_SETUP": 2,
12553
+ "DEV_ONBOARDING_PHASE_FINGERPRINT_SETUP": 3,
12554
+ "DEV_ONBOARDING_PHASE_SETUP_CHOICE": 4,
12555
+ "DEV_ONBOARDING_PHASE_WALLET_CREATE_START": 5,
12556
+ "DEV_ONBOARDING_PHASE_RECOVERY_PHRASE_VIEW": 6,
12557
+ "DEV_ONBOARDING_PHASE_RECOVERY_PHRASE_CONFIRM": 7,
12558
+ "DEV_ONBOARDING_PHASE_RESTORE_METHOD_CHOICE": 8,
12559
+ "DEV_ONBOARDING_PHASE_RECOVERY_PHRASE_RESTORE": 9,
12560
+ "DEV_ONBOARDING_PHASE_SEEDCARD_RESTORE": 10,
12561
+ "DEV_ONBOARDING_PHASE_WALLET_READY": 11,
12562
+ "DEV_ONBOARDING_PHASE_SEEDCARD_BACKUP_PROMPT": 12,
12563
+ "DEV_ONBOARDING_PHASE_SEEDCARD_BACKUP": 13
12564
+ }
12565
+ },
12566
+ "DevOnboardingSetupKind": {
12485
12567
  "values": {
12486
- "DEV_ONBOARDING_STAGE_UNKNOWN": 0,
12487
- "DEV_ONBOARDING_STAGE_SAFETY_CHECK": 1,
12488
- "DEV_ONBOARDING_STAGE_PERSONALIZATION": 2,
12489
- "DEV_ONBOARDING_STAGE_SELECT_SETUP_METHOD": 3,
12490
- "DEV_ONBOARDING_STAGE_NEW_DEVICE": 4,
12491
- "DEV_ONBOARDING_STAGE_SELECT_RESTORE_METHOD": 5,
12492
- "DEV_ONBOARDING_STAGE_RESTORE_MNEMONIC": 6,
12493
- "DEV_ONBOARDING_STAGE_RESTORE_SEEDCARD": 7,
12494
- "DEV_ONBOARDING_STAGE_WALLET_READY": 8,
12495
- "DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP_PROMPT": 9,
12496
- "DEV_ONBOARDING_STAGE_SELECT_SEEDCARD_BACKUP_METHOD": 10,
12497
- "DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP": 11,
12498
- "DEV_ONBOARDING_STAGE_DONE": 12
12568
+ "DEV_ONBOARDING_SETUP_KIND_UNKNOWN": 0,
12569
+ "DEV_ONBOARDING_SETUP_KIND_CHOICE": 1,
12570
+ "DEV_ONBOARDING_SETUP_KIND_CREATE": 2,
12571
+ "DEV_ONBOARDING_SETUP_KIND_RESTORE": 3
12572
+ }
12573
+ },
12574
+ "DevOnboardingSetupMethod": {
12575
+ "values": {
12576
+ "DEV_ONBOARDING_SETUP_METHOD_UNKNOWN": 0,
12577
+ "DEV_ONBOARDING_SETUP_METHOD_RECOVERY_PHRASE": 1,
12578
+ "DEV_ONBOARDING_SETUP_METHOD_SEEDCARD": 2
12579
+ }
12580
+ },
12581
+ "DevOnboardingSetupStatus": {
12582
+ "fields": {
12583
+ "kind": {
12584
+ "type": "DevOnboardingSetupKind",
12585
+ "id": 1
12586
+ },
12587
+ "method": {
12588
+ "type": "DevOnboardingSetupMethod",
12589
+ "id": 2
12590
+ }
12499
12591
  }
12500
12592
  },
12501
12593
  "DevGetOnboardingStatus": {
@@ -12503,18 +12595,25 @@
12503
12595
  },
12504
12596
  "DevOnboardingStatus": {
12505
12597
  "fields": {
12506
- "stage": {
12507
- "rule": "required",
12508
- "type": "DevOnboardingStage",
12598
+ "step": {
12599
+ "type": "DevOnboardingStep",
12509
12600
  "id": 1
12510
12601
  },
12511
- "status_code": {
12512
- "type": "uint32",
12602
+ "phase": {
12603
+ "type": "DevOnboardingPhase",
12513
12604
  "id": 2
12514
12605
  },
12515
- "detail_code": {
12516
- "type": "uint32",
12606
+ "setup": {
12607
+ "type": "DevOnboardingSetupStatus",
12517
12608
  "id": 3
12609
+ },
12610
+ "pin_set": {
12611
+ "type": "bool",
12612
+ "id": 4
12613
+ },
12614
+ "wallet_initialized": {
12615
+ "type": "bool",
12616
+ "id": 5
12518
12617
  }
12519
12618
  }
12520
12619
  },