@onekeyfe/hd-core 1.2.2-alpha.12 → 1.2.2-alpha.120

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 (67) hide show
  1. package/README.md +1 -1
  2. package/__tests__/AllNetworkGetAddressBase.tracing.test.ts +452 -9
  3. package/__tests__/DeviceCommands.test.ts +254 -1
  4. package/__tests__/core-error-output.test.ts +92 -1
  5. package/__tests__/device-lifecycle-events.test.ts +379 -15
  6. package/__tests__/open-wallet-session-error-response.test.ts +2 -2
  7. package/__tests__/open-wallet-session.test.ts +8 -411
  8. package/__tests__/protocol-v2.test.ts +86 -0
  9. package/__tests__/public-device-state-api.test.ts +2 -7
  10. package/__tests__/sol-sign-offchain-message.test.ts +64 -0
  11. package/dist/api/GetFeatures.d.ts.map +1 -1
  12. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  13. package/dist/api/OpenWalletSession.d.ts.map +1 -1
  14. package/dist/api/UploadPortfolio.d.ts +1 -0
  15. package/dist/api/UploadPortfolio.d.ts.map +1 -1
  16. package/dist/api/allnetwork/AllNetworkGetAddress.d.ts.map +1 -1
  17. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +6 -0
  18. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  19. package/dist/api/allnetwork/AllNetworkGetAddressByLoop.d.ts.map +1 -1
  20. package/dist/api/device/DeviceVerify.d.ts.map +1 -1
  21. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  22. package/dist/core/RequestQueue.d.ts +1 -0
  23. package/dist/core/RequestQueue.d.ts.map +1 -1
  24. package/dist/core/index.d.ts +3 -1
  25. package/dist/core/index.d.ts.map +1 -1
  26. package/dist/core/uiPromiseRegistry.d.ts +1 -1
  27. package/dist/device/Device.d.ts +2 -0
  28. package/dist/device/Device.d.ts.map +1 -1
  29. package/dist/device/DeviceCommands.d.ts +5 -4
  30. package/dist/device/DeviceCommands.d.ts.map +1 -1
  31. package/dist/index.d.ts +35 -30
  32. package/dist/index.js +402 -208
  33. package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
  34. package/dist/types/api/getFeatures.d.ts.map +1 -1
  35. package/dist/types/api/getPassphraseState.d.ts.map +1 -1
  36. package/dist/types/api/openWalletSession.d.ts +1 -10
  37. package/dist/types/api/openWalletSession.d.ts.map +1 -1
  38. package/dist/types/api/protocolV2.d.ts +3 -4
  39. package/dist/types/api/protocolV2.d.ts.map +1 -1
  40. package/dist/types/api/solSignOffchainMessage.d.ts +1 -0
  41. package/dist/types/api/solSignOffchainMessage.d.ts.map +1 -1
  42. package/dist/types/params.d.ts.map +1 -1
  43. package/dist/utils/patch.d.ts +1 -1
  44. package/dist/utils/patch.d.ts.map +1 -1
  45. package/package.json +4 -4
  46. package/src/api/GetFeatures.ts +1 -0
  47. package/src/api/GetPassphraseState.ts +1 -0
  48. package/src/api/OpenWalletSession.ts +7 -77
  49. package/src/api/UploadPortfolio.ts +5 -4
  50. package/src/api/allnetwork/AllNetworkGetAddress.ts +47 -20
  51. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +88 -22
  52. package/src/api/allnetwork/AllNetworkGetAddressByLoop.ts +3 -0
  53. package/src/api/device/DeviceVerify.ts +8 -0
  54. package/src/api/solana/SolSignOffchainMessage.ts +44 -4
  55. package/src/core/RequestQueue.ts +20 -0
  56. package/src/core/index.ts +116 -49
  57. package/src/data/messages/messages-protocol-v2.json +49 -33
  58. package/src/data/messages/messages.json +8 -5
  59. package/src/device/Device.ts +51 -27
  60. package/src/device/DeviceCommands.ts +29 -2
  61. package/src/protocols/protocol-v2/walletSession.ts +7 -0
  62. package/src/types/api/getFeatures.ts +2 -1
  63. package/src/types/api/getPassphraseState.ts +2 -5
  64. package/src/types/api/openWalletSession.ts +7 -19
  65. package/src/types/api/protocolV2.ts +3 -4
  66. package/src/types/api/solSignOffchainMessage.ts +2 -0
  67. package/src/types/params.ts +7 -0
@@ -11,7 +11,7 @@ import {
11
11
  } from '@onekeyfe/hd-transport';
12
12
 
13
13
  import TransportManager from '../data-manager/TransportManager';
14
- import { LoggerNames, getLogger, patchFeatures } from '../utils';
14
+ import { LoggerNames, getLogger, patchFeatures, wait } from '../utils';
15
15
  import { DEVICE, type PassphraseRequestPayload } from '../events';
16
16
  import { DeviceModelToTypes } from '../types';
17
17
  import {
@@ -198,6 +198,8 @@ export class DeviceCommands {
198
198
 
199
199
  disposed: boolean;
200
200
 
201
+ private disposalToken?: object;
202
+
201
203
  callPromise?: Promise<DefaultMessageResponse>;
202
204
 
203
205
  constructor(device: Device, mainId: string) {
@@ -212,6 +214,7 @@ export class DeviceCommands {
212
214
 
213
215
  async dispose(_cancelRequest: boolean) {
214
216
  this.disposed = true;
217
+ this.disposalToken = {};
215
218
  await this.transport.cancel?.();
216
219
  }
217
220
 
@@ -439,7 +442,31 @@ export class DeviceCommands {
439
442
  msg?: DefaultMessageResponse['message'],
440
443
  options?: TransportCallOptions
441
444
  ) {
442
- const resp = await this.call(type, msg, options);
445
+ const { disposalToken } = this;
446
+ let resp = await this.call(type, msg, options);
447
+ // Session busy failures precede wallet derivation or reject an occupied flow.
448
+ // Three retries cover the 240 ms PIN dismissal animation on older V2 firmware.
449
+ for (
450
+ let retry = 0;
451
+ retry < 3 &&
452
+ this.device.isProtocolV2() &&
453
+ DEVICE_SESSION_CALLS.has(type) &&
454
+ resp.type === 'Failure' &&
455
+ (resp.message.code as string | FailureType) === 'Failure_ProcessError' &&
456
+ resp.message.subcode === DeviceSessionErrorCode.DeviceSessionError_Busy;
457
+ retry += 1
458
+ ) {
459
+ await wait(100);
460
+ if (this.device.wasInterruptedByUser()) {
461
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
462
+ }
463
+ this.checkDisposed();
464
+ if (this.disposalToken !== disposalToken) {
465
+ // React Native can revive this instance. A stale retry must not release the new run.
466
+ throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'DeviceCommands lifecycle changed');
467
+ }
468
+ resp = await this.call(type, msg, options);
469
+ }
443
470
  return this._filterCommonTypes(resp, type, options);
444
471
  }
445
472
 
@@ -268,6 +268,7 @@ export async function getProtocolV2WalletSession(
268
268
  ? device.getInternalState()
269
269
  : undefined;
270
270
  let response;
271
+ let walletSelectionRequested = false;
271
272
  let resumed = false;
272
273
  let walletStatusRefreshed = false;
273
274
  const markWalletStatusRefreshed = () => {
@@ -482,6 +483,7 @@ export async function getProtocolV2WalletSession(
482
483
  throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
483
484
  }
484
485
  await lockAttachPinBeforePassphraseSelection();
486
+ walletSelectionRequested = true;
485
487
  response = await selectDeviceSession(
486
488
  device,
487
489
  expectedPassphraseState,
@@ -508,6 +510,11 @@ export async function getProtocolV2WalletSession(
508
510
  device.clearInternalState();
509
511
  throw ERRORS.TypedError(HardwareErrorCode.WalletSessionInvalid);
510
512
  }
513
+ // Report a fresh selection mismatch before asking for input again.
514
+ if (walletSelectionRequested) {
515
+ clearCurrentWalletSession();
516
+ throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
517
+ }
511
518
  if (options?.onlyMainPin) {
512
519
  device.clearStandardInternalState?.();
513
520
  await selectStandardWallet(true);
@@ -2,6 +2,7 @@ import type { CommonParams, Response } from '../params';
2
2
  import type { Features } from '../device';
3
3
 
4
4
  /**
5
- * @deprecated Use `getDeviceState` for both Protocol V1 and Protocol V2 devices.
5
+ * @deprecated Use `getDeviceState` for both Protocol V1 and Protocol V2.
6
+ * Existing calls still work. Read `payload.identity.deviceId` from `getDeviceState`.
6
7
  */
7
8
  export declare function getFeatures(connectId?: string, params?: CommonParams): Response<Features>;
@@ -3,11 +3,8 @@ import type { CommonParams, Response } from '../params';
3
3
  export type GetPassphraseStateParams = CommonParams;
4
4
 
5
5
  /**
6
- * Compatibility wallet-state API for existing App integrations.
7
- *
8
- * Protocol V1 keeps its parameterless firmware flow. Protocol V2 maps the existing
9
- * `useEmptyPassphrase` and `initSession` intent to the device-only wallet-session flow.
10
- * New integrations should prefer `openWalletSession` for explicit wallet intent.
6
+ * @deprecated Use `openWalletSession` for both Protocol V1 and Protocol V2.
7
+ * Existing calls still work. Persist `deviceId + passphraseState`; do not persist firmware `session_id`.
11
8
  */
12
9
  export declare function getPassphraseState(
13
10
  connectId?: string,
@@ -3,28 +3,16 @@ import type { CommonParams, Response } from '../params';
3
3
  export const OpenWalletSessionMode = {
4
4
  Standard: 'standard',
5
5
  SelectHidden: 'select-hidden',
6
- ResumeHidden: 'resume-hidden',
7
6
  } as const;
8
7
 
9
8
  export type OpenWalletSessionModeValue =
10
9
  (typeof OpenWalletSessionMode)[keyof typeof OpenWalletSessionMode];
11
10
 
12
- export type OpenWalletSessionParams =
13
- | {
14
- mode: typeof OpenWalletSessionMode.Standard;
15
- deviceId?: never;
16
- passphraseState?: never;
17
- }
18
- | {
19
- mode: typeof OpenWalletSessionMode.SelectHidden;
20
- deviceId?: never;
21
- passphraseState?: never;
22
- }
23
- | {
24
- mode: typeof OpenWalletSessionMode.ResumeHidden;
25
- deviceId: string;
26
- passphraseState: string;
27
- };
11
+ export type OpenWalletSessionParams = {
12
+ mode: OpenWalletSessionModeValue;
13
+ deviceId?: never;
14
+ passphraseState?: never;
15
+ };
28
16
 
29
17
  type OpenWalletSessionPayloadBase = {
30
18
  protocol: 'V1' | 'V2';
@@ -45,8 +33,8 @@ export type OpenWalletSessionPayload = OpenWalletSessionPayloadBase &
45
33
  );
46
34
 
47
35
  /**
48
- * Opens the standard, hidden, or Attach-to-PIN wallet flow through a unified
49
- * Protocol V1/V2 API.
36
+ * Opens the standard or hidden wallet through a unified Protocol V1/V2 API.
37
+ * Resume a bound hidden wallet by passing passphraseState on later methods.
50
38
  */
51
39
  export declare function openWalletSession(
52
40
  connectId: string,
@@ -1,6 +1,7 @@
1
1
  import type { CommonParams, Response } from '../params';
2
2
  import type { OnboardingStatus, Success } from '@onekeyfe/hd-transport';
3
3
  import type { DeviceRebootParams } from '../../api/protocol-v2/helpers';
4
+ import type { UploadPortfolioParams } from '../../api/UploadPortfolio';
4
5
  import type {
5
6
  DeviceUploadWallpaperParams,
6
7
  DeviceUploadWallpaperResponse,
@@ -12,6 +13,7 @@ import type {
12
13
 
13
14
  // Re-export implementation parameter types as the single source of truth.
14
15
  export type { DeviceRebootParams, RebootTypeInput } from '../../api/protocol-v2/helpers';
16
+ export type { UploadPortfolioParams } from '../../api/UploadPortfolio';
15
17
  export type {
16
18
  DeviceUploadWallpaperParams,
17
19
  DeviceUploadWallpaperResponse,
@@ -67,8 +69,5 @@ export declare function deviceUploadNft(
67
69
 
68
70
  export declare function uploadPortfolio(
69
71
  connectId: string,
70
- params: {
71
- packageBase64: string;
72
- timeoutMs?: number | string;
73
- }
72
+ params: UploadPortfolioParams
74
73
  ): Response<FileInfo & { portfolioUpdated: true }>;
@@ -15,6 +15,8 @@ export type SolSignOffchainMessageParams = {
15
15
  messageVersion?: SolanaOffChainMessageVersion;
16
16
  messageFormat?: SolanaOffChainMessageFormat;
17
17
  applicationDomainHex?: string;
18
+ /** 32-byte public keys encoded as hex, strictly sorted and unique. */
19
+ requiredSigners?: string[];
18
20
  };
19
21
 
20
22
  export declare function solSignOffchainMessage(
@@ -1,6 +1,13 @@
1
1
  import type { HardwareConnectProtocol } from '@onekeyfe/hd-shared';
2
2
 
3
3
  export interface CommonParams {
4
+ /**
5
+ * Keep the transport session after this call instead of releasing it.
6
+ * This is a Device.run() hold flag, not a wallet identity. It does not replace
7
+ * `useEmptyPassphrase`, `passphraseState`, or `openWalletSession`.
8
+ * USB multi-step flows and Electron BLE firmware windows still need this to
9
+ * avoid dropping the link between calls.
10
+ */
4
11
  keepSession?: boolean;
5
12
  /**
6
13
  * polling connect max retry count