@onekeyfe/hd-core 1.2.0-alpha.131 → 1.2.0-alpha.133

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.
@@ -1,7 +1,7 @@
1
1
  import { EDeviceType, ERRORS, HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
2
2
  import { DeviceType, TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
3
3
 
4
- import { initConnector, initCore } from '../src/core';
4
+ import { initConnector, initCore, isMissingDetectedProtocolV2Error } from '../src/core';
5
5
  import { DataManager } from '../src/data-manager';
6
6
  import TransportManager from '../src/data-manager/TransportManager';
7
7
  import { Device } from '../src/device/Device';
@@ -251,6 +251,22 @@ describe('public device lifecycle events', () => {
251
251
  expect(device.getProtocol()).toBe('V2');
252
252
  });
253
253
 
254
+ test.each([
255
+ ['V2', true],
256
+ ['V1', false],
257
+ ] as const)(
258
+ 'retries a missing detected protocol only for an explicit Protocol %s connection',
259
+ (connectProtocol, expected) => {
260
+ const method = { payload: { connectProtocol } } as never;
261
+ const error = {
262
+ errorCode: HardwareErrorCode.RuntimeError,
263
+ message: 'Device protocol has not been detected for ble-id',
264
+ };
265
+
266
+ expect(isMissingDetectedProtocolV2Error(method, error)).toBe(expected);
267
+ }
268
+ );
269
+
254
270
  test('converts an internal transport disconnect into a public KnownDevice snapshot', () => {
255
271
  jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
256
272
  core = initCore();
@@ -279,7 +279,7 @@ describe('DeviceSettings protocol routing', () => {
279
279
  );
280
280
  });
281
281
 
282
- it('uses the Pro2 passphrase page as a device-side toggle and verifies the target state', async () => {
282
+ it('uses the Pro2 passphrase page and refreshes device state after the toggle', async () => {
283
283
  const { device, typedCall, getDeviceState } = createDevice({ protocol: 'V2' });
284
284
  getDeviceState
285
285
  .mockResolvedValueOnce({
@@ -361,8 +361,8 @@ describe('DeviceSettings protocol routing', () => {
361
361
  expect(getDeviceState).toHaveBeenCalledWith({ refreshSections: ['settings'] });
362
362
  });
363
363
 
364
- it('rejects a successful Pro2 page response when the hardware did not reach the target', async () => {
365
- const { device, getDeviceState } = createDevice({ protocol: 'V2' });
364
+ it('does not overwrite Pro2 passphrase state when refreshed state does not match', async () => {
365
+ const { device, getDeviceState, updateState } = createDevice({ protocol: 'V2' });
366
366
  getDeviceState.mockResolvedValue({
367
367
  status: { passphraseProtection: false },
368
368
  });
@@ -376,14 +376,12 @@ describe('DeviceSettings protocol routing', () => {
376
376
  method.init();
377
377
  (method as any).device = device;
378
378
 
379
- await expect(method.run()).rejects.toMatchObject({
380
- errorCode: HardwareErrorCode.RuntimeError,
381
- message: 'Protocol V2 passphrase setting did not reach the requested value.',
382
- });
379
+ await expect(method.run()).resolves.toEqual({ message: 'Success' });
380
+ expect(updateState).not.toHaveBeenCalled();
383
381
  });
384
382
 
385
- it('accepts a locked Pro2 as confirmation after disabling passphrase', async () => {
386
- const { device, getDeviceState } = createDevice({ protocol: 'V2' });
383
+ it('keeps the previous Pro2 passphrase state when refreshed state is unavailable after locking', async () => {
384
+ const { device, getDeviceState, updateState } = createDevice({ protocol: 'V2' });
387
385
  getDeviceState
388
386
  .mockResolvedValueOnce({
389
387
  status: { unlocked: true, passphraseProtection: true },
@@ -402,6 +400,68 @@ describe('DeviceSettings protocol routing', () => {
402
400
  (method as any).device = device;
403
401
 
404
402
  await expect(method.run()).resolves.toEqual({ message: 'Success' });
403
+ expect(updateState).not.toHaveBeenCalled();
404
+ });
405
+
406
+ it('preserves confirmed Pro2 passphrase state when the post-toggle status is locked', async () => {
407
+ let statusReadCount = 0;
408
+ const typedCall = jest.fn().mockImplementation((requestType: string) => {
409
+ if (requestType === 'DeviceStatusGet') {
410
+ statusReadCount += 1;
411
+ return {
412
+ message:
413
+ statusReadCount === 1
414
+ ? { init_states: true, unlocked: true, passphrase_enabled: true }
415
+ : { init_states: true, unlocked: false, passphrase_enabled: false },
416
+ };
417
+ }
418
+ if (requestType === 'DeviceSettingsPageShow') {
419
+ return { message: { message: 'Success' } };
420
+ }
421
+ if (requestType === 'DeviceSettingsGet') {
422
+ return { message: { label: 'Pro 2' } };
423
+ }
424
+ throw new Error(`Unexpected request: ${requestType}`);
425
+ });
426
+ const device = Device.fromDescriptor({
427
+ id: 'pro2-passphrase',
428
+ path: 'pro2-passphrase',
429
+ protocolType: 'V2',
430
+ } as never);
431
+ (device as any).commands = { typedCall };
432
+ device.updateState(
433
+ {
434
+ protocol: 'V2',
435
+ identity: { deviceType: EDeviceType.Pro2 },
436
+ status: {
437
+ mode: 'normal',
438
+ unlocked: true,
439
+ passphraseProtection: true,
440
+ },
441
+ raw: {
442
+ protocolV2ProtocolInfo: {
443
+ version: 1,
444
+ supported_messages: [PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE],
445
+ },
446
+ },
447
+ },
448
+ 'initialize'
449
+ );
450
+ const method = new DeviceSettings({
451
+ id: 6,
452
+ payload: {
453
+ method: 'deviceSettings',
454
+ usePassphrase: false,
455
+ },
456
+ });
457
+ method.init();
458
+ (method as any).device = device;
459
+
460
+ await expect(method.run()).resolves.toEqual({ message: 'Success' });
461
+ expect(device.state?.status).toMatchObject({
462
+ unlocked: false,
463
+ passphraseProtection: true,
464
+ });
405
465
  });
406
466
 
407
467
  it('keeps Protocol V1 passphrase settings on ApplySettings', async () => {
@@ -265,6 +265,36 @@ describe('DeviceUploadWallpaper', () => {
265
265
  expect(typedCall.mock.calls.some(call => call[0] === 'DeviceSettingsSet')).toBe(false);
266
266
  });
267
267
 
268
+ test('returns success when wallpaper read-back fails after apply', async () => {
269
+ const typedCall = jest.fn().mockImplementation((request, _response, params) => {
270
+ if (request === 'FilesystemDirMake') return { message: {} };
271
+ if (request === 'FilesystemFileWrite') {
272
+ const file = params.file as { data: Uint8Array; offset: number };
273
+ return { message: { processed_byte: file.offset + file.data.byteLength } };
274
+ }
275
+ if (request === 'DeviceSettingsSet') {
276
+ return { message: { message: 'wallpaper applied' } };
277
+ }
278
+ throw new Error(`Unexpected request: ${request}`);
279
+ });
280
+ const method = new DeviceUploadWallpaper({
281
+ id: 1,
282
+ payload: {
283
+ method: 'deviceUploadWallpaper',
284
+ jpegBase64: createJpegBase64(604, 1024),
285
+ },
286
+ });
287
+ const device = stubWallpaperDevice({ commands: { typedCall } });
288
+ device.refreshProtocolV2SettingsAfterMutation.mockRejectedValueOnce(
289
+ new Error('settings read-back failed')
290
+ );
291
+ (method as any).device = device;
292
+ method.init();
293
+
294
+ await expect(method.run()).resolves.toMatchObject({ message: 'wallpaper applied' });
295
+ expect(device.refreshProtocolV2SettingsAfterMutation).toHaveBeenCalledTimes(1);
296
+ });
297
+
268
298
  test('rejects unsafe filenames before device communication', () => {
269
299
  const method = new DeviceUploadWallpaper({
270
300
  id: 1,
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceSettings.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceSettings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAgB3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA0D5D,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU,CAAC,aAAa,CAAC;IACnE,qBAAqB;IAIrB,IAAI;IA0EJ,eAAe;;;;;;;IAWT,GAAG;CAwIV"}
1
+ {"version":3,"file":"DeviceSettings.d.ts","sourceRoot":"","sources":["../../../src/api/device/DeviceSettings.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAgB3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA0D5D,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,UAAU,CAAC,aAAa,CAAC;IACnE,qBAAqB;IAIrB,IAAI;IA0EJ,eAAe;;;;;;;IAWT,GAAG;CA2HV"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceUploadWallpaper.d.ts","sourceRoot":"","sources":["../../../src/api/protocol-v2/DeviceUploadWallpaper.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3C,OAAO,EAGL,KAAK,wBAAwB,EAE9B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAkBF,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,UAAU,CAAC,2BAA2B,CAAC;IACxF,qBAAqB;IAIrB,OAAO,CAAC,OAAO,CAAC,CAA8D;IAE9E,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,IAAI,CAAM;IAElB,IAAI;YAwBU,kBAAkB;YAgBlB,eAAe;YAaf,MAAM;IAwBd,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC;CAiBpD"}
1
+ {"version":3,"file":"DeviceUploadWallpaper.d.ts","sourceRoot":"","sources":["../../../src/api/protocol-v2/DeviceUploadWallpaper.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAO3C,OAAO,EAGL,KAAK,wBAAwB,EAE9B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,2BAA2B,GAAG;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAmBF,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,UAAU,CAAC,2BAA2B,CAAC;IACxF,qBAAqB;IAIrB,OAAO,CAAC,OAAO,CAAC,CAA8D;IAE9E,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,IAAI,CAAM;IAElB,IAAI;YAwBU,kBAAkB;YAgBlB,eAAe;YAaf,MAAM;IAwBd,GAAG,IAAI,OAAO,CAAC,6BAA6B,CAAC;CAyBpD"}
@@ -5,8 +5,10 @@ import DeviceConnector from '../device/DeviceConnector';
5
5
  import type { ConnectSettings } from '../types';
6
6
  import type { CoreMessage } from '../events';
7
7
  import type { LowlevelTransportSharedPlugin } from '@onekeyfe/hd-transport';
8
+ import type { BaseMethod } from '../api/BaseMethod';
8
9
  export type CoreContext = ReturnType<Core['getCoreContext']>;
9
10
  export declare const callAPI: (context: CoreContext, message: CoreMessage) => Promise<any>;
11
+ export declare function isMissingDetectedProtocolV2Error(method: BaseMethod, error: unknown): boolean;
10
12
  export declare const cancel: (context: CoreContext, connectId?: string) => void;
11
13
  export declare const onDeviceButtonHandler: (__0_0: Device, __0_1: import("../events").DeviceButtonRequestPayload) => void;
12
14
  export default class Core extends EventEmitter {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAoClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EACV,6BAA6B,EAG9B,MAAM,wBAAwB,CAAC;AAYhC,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAmE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AAw6BF,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAqF9D,CAAC;AAmGF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAiLF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,sBAAsB,CAAoC;IAElE,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IA6BhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";AACA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAoClC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAsB1C,OAAO,eAAe,MAAM,2BAA2B,CAAC;AAYxD,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAmD,MAAM,WAAW,CAAC;AAI9F,OAAO,KAAK,EACV,6BAA6B,EAG9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAmE7D,eAAO,MAAM,OAAO,YAAmB,WAAW,WAAW,WAAW,iBAoFvE,CAAC;AA2qBF,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,WAQlF;AAsPD,eAAO,MAAM,MAAM,YAAa,WAAW,cAAc,MAAM,SAqF9D,CAAC;AAmGF,eAAO,MAAM,qBAAqB,gFAejC,CAAC;AAiLF,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAoB;IAE1C,SAAgB,aAAa,EAAE,MAAM,CAAC;IAEtC,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,cAAc,CAAC,CAAgB;IAGvC,OAAO,CAAC,sBAAsB,CAAoC;IAElE,OAAO,CAAC,iBAAiB,CAAoB;;IAS7C,OAAO,CAAC,cAAc;IA6BhB,aAAa,CAAC,OAAO,EAAE,WAAW;IAuExC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAOV,gBAAgB;CAiC/B;AAED,eAAO,MAAM,QAAQ,YAIpB,CAAC;AAEF,eAAO,MAAM,aAAa,uBAYzB,CAAC;AAMF,eAAO,MAAM,IAAI,aACL,eAAe,aACd,GAAG,WACL,6BAA6B,8BAiBvC,CAAC;AAEF,eAAO,MAAM,eAAe;SAKrB,eAAe,CAAC,KAAK,CAAC;eAChB,GAAG;;UASf,CAAC"}