@onekeyfe/hd-core 0.0.10 → 0.1.2

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 (85) hide show
  1. package/dist/api/BaseMethod.d.ts +2 -0
  2. package/dist/api/BaseMethod.d.ts.map +1 -1
  3. package/dist/api/CheckBLEFirmwareRelease.d.ts +8 -1
  4. package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
  5. package/dist/api/CheckFirmwareRelease.d.ts +8 -1
  6. package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
  7. package/dist/api/FirmwareUpdate.d.ts +14 -0
  8. package/dist/api/FirmwareUpdate.d.ts.map +1 -0
  9. package/dist/api/firmware/getBinary.d.ts +33 -0
  10. package/dist/api/firmware/getBinary.d.ts.map +1 -0
  11. package/dist/api/firmware/uploadFirmware.d.ts +8 -0
  12. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -0
  13. package/dist/api/index.d.ts +1 -0
  14. package/dist/api/index.d.ts.map +1 -1
  15. package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
  16. package/dist/constants/errors.d.ts +2 -0
  17. package/dist/constants/errors.d.ts.map +1 -1
  18. package/dist/core/index.d.ts +1 -0
  19. package/dist/core/index.d.ts.map +1 -1
  20. package/dist/data-manager/DataManager.d.ts +10 -0
  21. package/dist/data-manager/DataManager.d.ts.map +1 -1
  22. package/dist/device/Device.d.ts +3 -1
  23. package/dist/device/Device.d.ts.map +1 -1
  24. package/dist/device/DeviceCommands.d.ts +1 -0
  25. package/dist/device/DeviceCommands.d.ts.map +1 -1
  26. package/dist/device/DeviceList.d.ts.map +1 -1
  27. package/dist/events/call.d.ts +7 -0
  28. package/dist/events/call.d.ts.map +1 -1
  29. package/dist/events/core.d.ts +2 -2
  30. package/dist/events/core.d.ts.map +1 -1
  31. package/dist/events/iframe.d.ts +1 -0
  32. package/dist/events/iframe.d.ts.map +1 -1
  33. package/dist/events/ui-request.d.ts +9 -1
  34. package/dist/events/ui-request.d.ts.map +1 -1
  35. package/dist/index.d.ts +108 -9
  36. package/dist/index.js +269 -50
  37. package/dist/inject.d.ts.map +1 -1
  38. package/dist/types/api/checkBLEFirmwareRelease.d.ts +12 -2
  39. package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
  40. package/dist/types/api/checkFirmwareRelease.d.ts +11 -1
  41. package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
  42. package/dist/types/api/firmwareUpdate.d.ts +13 -0
  43. package/dist/types/api/firmwareUpdate.d.ts.map +1 -0
  44. package/dist/types/api/index.d.ts +3 -1
  45. package/dist/types/api/index.d.ts.map +1 -1
  46. package/dist/types/device.d.ts +38 -0
  47. package/dist/types/device.d.ts.map +1 -1
  48. package/dist/types/firmware.d.ts +2 -1
  49. package/dist/types/firmware.d.ts.map +1 -1
  50. package/dist/types/params.d.ts +3 -0
  51. package/dist/types/params.d.ts.map +1 -1
  52. package/dist/utils/assets.d.ts +1 -1
  53. package/dist/utils/assets.d.ts.map +1 -1
  54. package/dist/utils/networkUtils.d.ts.map +1 -1
  55. package/dist/utils/release.d.ts +4 -0
  56. package/dist/utils/release.d.ts.map +1 -0
  57. package/package.json +3 -3
  58. package/src/api/BaseMethod.ts +4 -0
  59. package/src/api/CheckBLEFirmwareRelease.ts +7 -1
  60. package/src/api/CheckFirmwareRelease.ts +7 -1
  61. package/src/api/FirmwareUpdate.ts +78 -0
  62. package/src/api/firmware/getBinary.ts +46 -0
  63. package/src/api/firmware/uploadFirmware.ts +72 -0
  64. package/src/api/index.ts +2 -0
  65. package/src/constants/errors.ts +2 -0
  66. package/src/core/index.ts +29 -1
  67. package/src/data-manager/DataManager.ts +36 -20
  68. package/src/device/Device.ts +22 -11
  69. package/src/device/DeviceCommands.ts +6 -0
  70. package/src/device/DeviceList.ts +13 -1
  71. package/src/events/call.ts +6 -0
  72. package/src/events/core.ts +2 -1
  73. package/src/events/iframe.ts +1 -0
  74. package/src/events/ui-request.ts +15 -1
  75. package/src/inject.ts +2 -0
  76. package/src/types/api/checkBLEFirmwareRelease.ts +12 -4
  77. package/src/types/api/checkFirmwareRelease.ts +11 -1
  78. package/src/types/api/firmwareUpdate.ts +21 -0
  79. package/src/types/api/index.ts +4 -1
  80. package/src/types/device.ts +44 -0
  81. package/src/types/firmware.ts +2 -1
  82. package/src/types/params.ts +2 -0
  83. package/src/utils/assets.ts +1 -1
  84. package/src/utils/networkUtils.ts +3 -1
  85. package/src/utils/release.ts +24 -0
@@ -85,8 +85,6 @@ export class Device extends EventEmitter {
85
85
 
86
86
  internalState: string[] = [];
87
87
 
88
- loaded = false;
89
-
90
88
  needReloadDevice = false;
91
89
 
92
90
  /**
@@ -225,6 +223,10 @@ export class Device extends EventEmitter {
225
223
  }
226
224
  }
227
225
 
226
+ getCommands() {
227
+ return this.commands;
228
+ }
229
+
228
230
  getInternalState() {
229
231
  return this.internalState[this.instance];
230
232
  }
@@ -277,10 +279,19 @@ export class Device extends EventEmitter {
277
279
  }
278
280
  }
279
281
 
282
+ updateFromCache(device: Device) {
283
+ this.mainId = device.mainId;
284
+ this.commands = device.commands;
285
+ this.updateDescriptor(device.originalDescriptor);
286
+ if (device.features) {
287
+ this._updateFeatures(device.features);
288
+ }
289
+ }
290
+
280
291
  async run(fn?: () => Promise<void>, options?: RunOptions) {
281
292
  if (this.runPromise) {
282
- Log.error('[Device] run error:', 'Device is running');
283
- throw ERRORS.TypedError('Device_CallInProgress');
293
+ this.interruption();
294
+ Log.debug('[Device] run error:', 'Device is running, but will cancel previous operate');
284
295
  }
285
296
 
286
297
  options = parseRunOptions(options);
@@ -315,11 +326,6 @@ export class Device extends EventEmitter {
315
326
  await fn();
316
327
  }
317
328
 
318
- // reload features
319
- if (this.loaded && this.features) {
320
- await this.getFeatures();
321
- }
322
-
323
329
  if (
324
330
  (!this.keepSession && typeof options.keepSession !== 'boolean') ||
325
331
  options.keepSession === false
@@ -334,9 +340,14 @@ export class Device extends EventEmitter {
334
340
  }
335
341
 
336
342
  this.runPromise = null;
343
+ }
337
344
 
338
- if (!this.loaded) {
339
- this.loaded = true;
345
+ interruption() {
346
+ if (this.commands) {
347
+ this.commands.dispose();
348
+ }
349
+ if (this.runPromise) {
350
+ this.runPromise.reject(ERRORS.TypedError('Device_Interrupted'));
340
351
  }
341
352
  }
342
353
 
@@ -56,7 +56,11 @@ export class DeviceCommands {
56
56
 
57
57
  dispose() {
58
58
  this.disposed = true;
59
+ if (this._cancelableRequest) {
60
+ this._cancelableRequest();
61
+ }
59
62
  this._cancelableRequest = undefined;
63
+ this.transport.cancel?.();
60
64
  }
61
65
 
62
66
  // Sends an async message to the opened device.
@@ -205,3 +209,5 @@ export class DeviceCommands {
205
209
  });
206
210
  }
207
211
  }
212
+
213
+ export type TypedCall = DeviceCommands['typedCall'];
@@ -2,6 +2,11 @@ import EventEmitter from 'events';
2
2
  import DeviceConnector from './DeviceConnector';
3
3
  import { Device } from './Device';
4
4
  import { getDeviceUUID } from '../utils/deviceFeaturesUtils';
5
+ import { initLog } from '../utils';
6
+
7
+ const cacheDeviceMap = new Map<string, Device>();
8
+
9
+ const Log = initLog('DeviceList');
5
10
 
6
11
  export class DeviceList extends EventEmitter {
7
12
  devices: Record<string, Device> = {};
@@ -20,7 +25,7 @@ export class DeviceList extends EventEmitter {
20
25
  const deviceList = [];
21
26
  console.log('get device list');
22
27
  for await (const descriptor of descriptorList) {
23
- const device = Device.fromDescriptor(descriptor);
28
+ let device = Device.fromDescriptor(descriptor);
24
29
  device.deviceConnector = this.connector;
25
30
  await device.connect();
26
31
  await device.initialize();
@@ -30,7 +35,14 @@ export class DeviceList extends EventEmitter {
30
35
  deviceList.push(device);
31
36
  if (device.features) {
32
37
  const uuid = getDeviceUUID(device.features);
38
+ if (cacheDeviceMap.has(uuid)) {
39
+ const cache = cacheDeviceMap.get(uuid);
40
+ cache?.updateFromCache(device);
41
+ device = cache as Device;
42
+ Log.debug('use cache device: ', uuid);
43
+ }
33
44
  this.devices[uuid] = device;
45
+ cacheDeviceMap.set(uuid, device);
34
46
  }
35
47
  }
36
48
 
@@ -46,6 +46,12 @@ export interface IFrameCallMessage {
46
46
  payload: CallMethodPayload;
47
47
  }
48
48
 
49
+ export interface IFrameCancelMessage {
50
+ event: typeof IFRAME.CANCEL;
51
+ type: typeof IFRAME.CANCEL;
52
+ payload: { connectId?: string };
53
+ }
54
+
49
55
  export const RESPONSE_EVENT = 'RESPONSE_EVENT';
50
56
 
51
57
  export interface MethodResponseMessage {
@@ -1,5 +1,5 @@
1
1
  import { Unsuccessful } from '../types/params';
2
- import { IFrameCallMessage } from './call';
2
+ import { IFrameCallMessage, IFrameCancelMessage } from './call';
3
3
  import { DeviceEventMessage } from './device';
4
4
  import { IFrameEventMessage } from './iframe';
5
5
  import { UiEventMessage } from './ui-request';
@@ -13,6 +13,7 @@ export type CoreMessage = {
13
13
  } & (
14
14
  | IFrameEventMessage
15
15
  | IFrameCallMessage
16
+ | IFrameCancelMessage
16
17
  | UiResponseMessage
17
18
  | UiEventMessage
18
19
  | DeviceEventMessage
@@ -6,6 +6,7 @@ export const IFRAME = {
6
6
  INIT: 'iframe-init',
7
7
  INIT_BRIDGE: 'iframe-init-bridge',
8
8
  CALL: 'iframe-call',
9
+ CANCEL: 'iframe-cancel',
9
10
  } as const;
10
11
 
11
12
  export interface IFrameInit {
@@ -14,6 +14,8 @@ export const UI_REQUEST = {
14
14
 
15
15
  BLUETOOTH_PERMISSION: 'ui-bluetooth_permission',
16
16
  LOCATION_PERMISSION: 'ui-location_permission',
17
+
18
+ FIRMWARE_PROGRESS: 'ui-firmware-progress',
17
19
  } as const;
18
20
 
19
21
  export interface UiRequestWithoutPayload {
@@ -37,7 +39,19 @@ export interface UiRequestButton {
37
39
  payload: DeviceButtonRequest['payload'];
38
40
  }
39
41
 
40
- export type UiEvent = UiRequestWithoutPayload | UiRequestDeviceAction | UiRequestButton;
42
+ export interface FirmwareProgress {
43
+ type: typeof UI_REQUEST.FIRMWARE_PROGRESS;
44
+ payload: {
45
+ device: Device;
46
+ progress: number;
47
+ };
48
+ }
49
+
50
+ export type UiEvent =
51
+ | UiRequestWithoutPayload
52
+ | UiRequestDeviceAction
53
+ | UiRequestButton
54
+ | FirmwareProgress;
41
55
 
42
56
  export type UiEventMessage = UiEvent & { event: typeof UI_EVENT };
43
57
 
package/src/inject.ts CHANGED
@@ -124,6 +124,8 @@ export const inject = ({
124
124
  call({ ...params, connectId, method: 'stellarGetAddress' }),
125
125
  stellarSignTransaction: (connectId, params) =>
126
126
  call({ ...params, connectId, method: 'stellarSignTransaction' }),
127
+
128
+ firmwareUpdate: (connectId, params) => call({ ...params, connectId, method: 'firmwareUpdate' }),
127
129
  };
128
130
  return api;
129
131
  };
@@ -1,6 +1,14 @@
1
1
  import type { Response } from '../params';
2
- import type { IDeviceFirmwareStatus } from '../device';
2
+ import type { IDeviceBLEFirmwareStatus } from '../device';
3
+ import { IBLEFirmwareReleaseInfo } from '../settings';
3
4
 
4
- export declare function checkBLEFirmwareRelease(
5
- connectId?: string
6
- ): Response<IDeviceFirmwareStatus>;
5
+ type BleFirmwareRelease = {
6
+ status: IDeviceBLEFirmwareStatus;
7
+ changelog: {
8
+ 'zh-CN': string;
9
+ 'en-US': string;
10
+ }[];
11
+ release: IBLEFirmwareReleaseInfo;
12
+ };
13
+
14
+ export declare function checkBLEFirmwareRelease(connectId?: string): Response<BleFirmwareRelease>;
@@ -1,4 +1,14 @@
1
1
  import type { Response } from '../params';
2
2
  import type { IDeviceFirmwareStatus } from '../device';
3
+ import { IFirmwareReleaseInfo } from '../settings';
3
4
 
4
- export declare function checkFirmwareRelease(connectId?: string): Response<IDeviceFirmwareStatus>;
5
+ type FirmwareRelease = {
6
+ status: IDeviceFirmwareStatus;
7
+ changelog: {
8
+ 'en-US': string;
9
+ 'zh-CN': string;
10
+ }[];
11
+ release: IFirmwareReleaseInfo;
12
+ };
13
+
14
+ export declare function checkFirmwareRelease(connectId?: string): Response<FirmwareRelease>;
@@ -0,0 +1,21 @@
1
+ import type { PROTO } from '../../constants';
2
+ import type { Params, Response } from '../params';
3
+
4
+ export interface FirmwareUpdateBinary {
5
+ binary: ArrayBuffer;
6
+ }
7
+
8
+ export interface FirmwareUpdate {
9
+ version: number[];
10
+ btcOnly?: boolean;
11
+ updateType: 'firmware' | 'ble';
12
+ }
13
+
14
+ export declare function firmwareUpdate(
15
+ connectId: string | undefined,
16
+ params: Params<FirmwareUpdate>
17
+ ): Response<PROTO.Success>;
18
+ export declare function firmwareUpdate(
19
+ connectId: string | undefined,
20
+ params: Params<FirmwareUpdateBinary>
21
+ ): Response<PROTO.Success>;
@@ -39,6 +39,7 @@ import { solSignTransaction } from './solSignTransaction';
39
39
  import { stellarGetAddress } from './stellarGetAddress';
40
40
  import { stellarSignTransaction } from './stellarSignTransaction';
41
41
  import { cipherKeyValue } from './cipherKeyValue';
42
+ import { firmwareUpdate } from './firmwareUpdate';
42
43
 
43
44
  export * from './export';
44
45
 
@@ -53,7 +54,7 @@ export type CoreApi = {
53
54
  dispose: () => void;
54
55
  call: (params: any) => Promise<any>;
55
56
  uiResponse: typeof uiResponse;
56
- cancel: (params?: string) => void;
57
+ cancel: (connectId?: string) => void;
57
58
 
58
59
  /**
59
60
  * Core function
@@ -108,4 +109,6 @@ export type CoreApi = {
108
109
 
109
110
  stellarGetAddress: typeof stellarGetAddress;
110
111
  stellarSignTransaction: typeof stellarSignTransaction;
112
+
113
+ firmwareUpdate: typeof firmwareUpdate;
111
114
  };
@@ -86,3 +86,47 @@ export type ITransportStatus = 'valid' | 'outdated';
86
86
  export type DeviceFirmwareRange = {
87
87
  [deviceType in IDeviceType | IDeviceModel]?: { min: string; max?: string };
88
88
  };
89
+
90
+ type FeaturesNarrowing =
91
+ | {
92
+ major_version: 2;
93
+ fw_major: null;
94
+ fw_minor: null;
95
+ fw_patch: null;
96
+ bootloader_mode: true;
97
+ firmware_present: false;
98
+ }
99
+ | {
100
+ major_version: 2;
101
+ fw_major: null;
102
+ fw_minor: null;
103
+ fw_patch: null;
104
+ bootloader_mode: null;
105
+ firmware_present: null;
106
+ }
107
+ | {
108
+ major_version: 2;
109
+ fw_major: 2;
110
+ fw_minor: number;
111
+ fw_patch: number;
112
+ bootloader_mode: true;
113
+ firmware_present: true;
114
+ }
115
+ | {
116
+ major_version: 1;
117
+ fw_major: null;
118
+ fw_minor: null;
119
+ fw_patch: null;
120
+ bootloader_mode: true;
121
+ firmware_present: false;
122
+ }
123
+ | {
124
+ major_version: 1;
125
+ fw_major: null;
126
+ fw_minor: null;
127
+ fw_patch: null;
128
+ bootloader_mode: true;
129
+ firmware_present: true;
130
+ };
131
+
132
+ export type StrictFeatures = Features & FeaturesNarrowing;
@@ -9,7 +9,8 @@ export interface FirmwareRange {
9
9
  };
10
10
  }
11
11
 
12
- export type VersionArray = [1 | 2, number, number];
12
+ export type MajorVersion = 1 | 2;
13
+ export type VersionArray = [MajorVersion, number, number];
13
14
 
14
15
  export type FirmwareRelease = {
15
16
  required: boolean;
@@ -2,6 +2,8 @@ export interface CommonParams {
2
2
  keepSession?: boolean;
3
3
  }
4
4
 
5
+ export type Params<T> = CommonParams & T & { bundle?: undefined };
6
+
5
7
  export interface Unsuccessful {
6
8
  success: false;
7
9
  payload: { error: string; code?: string };
@@ -1,5 +1,5 @@
1
1
  import { httpRequest as browserHttpRequest } from './networkUtils';
2
2
 
3
- export const httpRequest = (url: string, _type: string): any => browserHttpRequest(url);
3
+ export const httpRequest = (url: string, type: string): any => browserHttpRequest(url, type);
4
4
 
5
5
  export const getTimeStamp = () => new Date().getTime();
@@ -4,13 +4,15 @@ export const httpRequest = async (url: string, type = 'text') => {
4
4
  const response = await axios.request({
5
5
  url,
6
6
  withCredentials: false,
7
+ responseType: type === 'binary' ? 'arraybuffer' : 'json',
7
8
  });
9
+
8
10
  if (+response.status === 200) {
9
11
  if (type === 'json') {
10
12
  return response.data;
11
13
  }
12
14
  if (type === 'binary') {
13
- return response.data.arrayBuffer();
15
+ return response.data;
14
16
  }
15
17
  return response.data;
16
18
  }
@@ -0,0 +1,24 @@
1
+ import semver from 'semver';
2
+ import { IBLEFirmwareReleaseInfo, IDeviceFirmwareStatus, IFirmwareReleaseInfo } from '../types';
3
+
4
+ export const getReleaseStatus = (
5
+ releases: (IFirmwareReleaseInfo | IBLEFirmwareReleaseInfo)[],
6
+ currentVersion: string
7
+ ): IDeviceFirmwareStatus => {
8
+ const newVersions = releases.filter(r => semver.gt(r.version.join('.'), currentVersion));
9
+ if (newVersions.length === 0) {
10
+ return 'valid';
11
+ }
12
+ if (newVersions.some(r => r.required)) {
13
+ return 'required';
14
+ }
15
+ return 'outdated';
16
+ };
17
+
18
+ export const getReleaseChangelog = (
19
+ releases: (IFirmwareReleaseInfo | IBLEFirmwareReleaseInfo)[],
20
+ currentVersion: string
21
+ ): IFirmwareReleaseInfo['changelog'][] => {
22
+ const newVersions = releases.filter(r => semver.gt(r.version.join('.'), currentVersion));
23
+ return newVersions.map(r => r.changelog);
24
+ };