@onekeyfe/hd-core 0.0.8 → 0.1.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 (119) hide show
  1. package/dist/api/BaseMethod.d.ts +4 -0
  2. package/dist/api/BaseMethod.d.ts.map +1 -1
  3. package/dist/api/CipherKeyValue.d.ts +9 -0
  4. package/dist/api/CipherKeyValue.d.ts.map +1 -0
  5. package/dist/api/FirmwareUpdate.d.ts +14 -0
  6. package/dist/api/FirmwareUpdate.d.ts.map +1 -0
  7. package/dist/api/device/DeviceRebootToBootloader.d.ts +8 -0
  8. package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
  9. package/dist/api/evm/EVMSignMessageEIP712.d.ts +5 -0
  10. package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
  11. package/dist/api/evm/EVMSignTransaction.d.ts +5 -0
  12. package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
  13. package/dist/api/evm/EVMSignTypedData.d.ts +7 -1
  14. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  15. package/dist/api/firmware/getBinary.d.ts +33 -0
  16. package/dist/api/firmware/getBinary.d.ts.map +1 -0
  17. package/dist/api/firmware/uploadFirmware.d.ts +8 -0
  18. package/dist/api/firmware/uploadFirmware.d.ts.map +1 -0
  19. package/dist/api/helpers/hexUtils.d.ts.map +1 -1
  20. package/dist/api/index.d.ts +8 -0
  21. package/dist/api/index.d.ts.map +1 -1
  22. package/dist/api/nem/NEMGetAddress.d.ts +9 -0
  23. package/dist/api/nem/NEMGetAddress.d.ts.map +1 -0
  24. package/dist/api/nem/NEMSignTransaction.d.ts +20 -0
  25. package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -0
  26. package/dist/api/solana/SolGetAddress.d.ts +9 -0
  27. package/dist/api/solana/SolGetAddress.d.ts.map +1 -0
  28. package/dist/api/solana/SolSignTransaction.d.ts +17 -0
  29. package/dist/api/solana/SolSignTransaction.d.ts.map +1 -0
  30. package/dist/api/stellar/StellarGetAddress.d.ts +9 -0
  31. package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -0
  32. package/dist/api/stellar/StellarSignTransaction.d.ts +335 -0
  33. package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -0
  34. package/dist/constants/errors.d.ts +1 -0
  35. package/dist/constants/errors.d.ts.map +1 -1
  36. package/dist/core/index.d.ts.map +1 -1
  37. package/dist/data/version.d.ts +1 -1
  38. package/dist/data/version.d.ts.map +1 -1
  39. package/dist/device/Device.d.ts +1 -0
  40. package/dist/device/Device.d.ts.map +1 -1
  41. package/dist/device/DeviceCommands.d.ts +1 -0
  42. package/dist/device/DeviceCommands.d.ts.map +1 -1
  43. package/dist/events/ui-request.d.ts +9 -1
  44. package/dist/events/ui-request.d.ts.map +1 -1
  45. package/dist/index.d.ts +364 -5
  46. package/dist/index.js +845 -21
  47. package/dist/inject.d.ts.map +1 -1
  48. package/dist/types/api/cipherKeyValue.d.ts +19 -0
  49. package/dist/types/api/cipherKeyValue.d.ts.map +1 -0
  50. package/dist/types/api/export.d.ts +7 -0
  51. package/dist/types/api/export.d.ts.map +1 -1
  52. package/dist/types/api/firmwareUpdate.d.ts +13 -0
  53. package/dist/types/api/firmwareUpdate.d.ts.map +1 -0
  54. package/dist/types/api/index.d.ts +16 -0
  55. package/dist/types/api/index.d.ts.map +1 -1
  56. package/dist/types/api/nemGetAddress.d.ts +15 -0
  57. package/dist/types/api/nemGetAddress.d.ts.map +1 -0
  58. package/dist/types/api/nemSignTransaction.d.ts +93 -0
  59. package/dist/types/api/nemSignTransaction.d.ts.map +1 -0
  60. package/dist/types/api/solGetAddress.d.ts +14 -0
  61. package/dist/types/api/solGetAddress.d.ts.map +1 -0
  62. package/dist/types/api/solSignTransaction.d.ts +14 -0
  63. package/dist/types/api/solSignTransaction.d.ts.map +1 -0
  64. package/dist/types/api/stellarGetAddress.d.ts +14 -0
  65. package/dist/types/api/stellarGetAddress.d.ts.map +1 -0
  66. package/dist/types/api/stellarSignTransaction.d.ts +130 -0
  67. package/dist/types/api/stellarSignTransaction.d.ts.map +1 -0
  68. package/dist/types/device.d.ts +45 -0
  69. package/dist/types/device.d.ts.map +1 -1
  70. package/dist/types/firmware.d.ts +2 -1
  71. package/dist/types/firmware.d.ts.map +1 -1
  72. package/dist/types/params.d.ts +3 -0
  73. package/dist/types/params.d.ts.map +1 -1
  74. package/dist/utils/assets.d.ts +1 -1
  75. package/dist/utils/assets.d.ts.map +1 -1
  76. package/dist/utils/deviceFeaturesUtils.d.ts +49 -2
  77. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  78. package/dist/utils/networkUtils.d.ts.map +1 -1
  79. package/package.json +3 -3
  80. package/src/api/BaseMethod.ts +9 -0
  81. package/src/api/CipherKeyValue.ts +66 -0
  82. package/src/api/FirmwareUpdate.ts +78 -0
  83. package/src/api/device/DeviceRebootToBootloader.ts +11 -0
  84. package/src/api/evm/EVMSignMessageEIP712.ts +8 -0
  85. package/src/api/evm/EVMSignTransaction.ts +15 -0
  86. package/src/api/evm/EVMSignTypedData.ts +55 -15
  87. package/src/api/firmware/getBinary.ts +46 -0
  88. package/src/api/firmware/uploadFirmware.ts +72 -0
  89. package/src/api/helpers/hexUtils.ts +0 -1
  90. package/src/api/index.ts +12 -0
  91. package/src/api/nem/NEMGetAddress.ts +61 -0
  92. package/src/api/nem/NEMSignTransaction.ts +246 -0
  93. package/src/api/solana/SolGetAddress.ts +59 -0
  94. package/src/api/solana/SolSignTransaction.ts +69 -0
  95. package/src/api/stellar/StellarGetAddress.ts +59 -0
  96. package/src/api/stellar/StellarSignTransaction.ts +213 -0
  97. package/src/constants/errors.ts +1 -0
  98. package/src/core/index.ts +40 -5
  99. package/src/data/version.ts +1 -1
  100. package/src/device/Device.ts +4 -0
  101. package/src/device/DeviceCommands.ts +2 -0
  102. package/src/events/ui-request.ts +15 -1
  103. package/src/inject.ts +17 -0
  104. package/src/types/api/cipherKeyValue.ts +26 -0
  105. package/src/types/api/export.ts +27 -0
  106. package/src/types/api/firmwareUpdate.ts +21 -0
  107. package/src/types/api/index.ts +21 -0
  108. package/src/types/api/nemGetAddress.ts +22 -0
  109. package/src/types/api/nemSignTransaction.ts +117 -0
  110. package/src/types/api/solGetAddress.ts +21 -0
  111. package/src/types/api/solSignTransaction.ts +21 -0
  112. package/src/types/api/stellarGetAddress.ts +21 -0
  113. package/src/types/api/stellarSignTransaction.ts +153 -0
  114. package/src/types/device.ts +52 -0
  115. package/src/types/firmware.ts +2 -1
  116. package/src/types/params.ts +2 -0
  117. package/src/utils/assets.ts +1 -1
  118. package/src/utils/deviceFeaturesUtils.ts +16 -2
  119. package/src/utils/networkUtils.ts +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"networkUtils.d.ts","sourceRoot":"","sources":["../../src/utils/networkUtils.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,QAAe,MAAM,gCAe5C,CAAC"}
1
+ {"version":3,"file":"networkUtils.d.ts","sourceRoot":"","sources":["../../src/utils/networkUtils.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,QAAe,MAAM,gCAiB5C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "> TODO: description",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -25,7 +25,7 @@
25
25
  "url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-transport": "^0.0.8",
28
+ "@onekeyfe/hd-transport": "^0.1.0",
29
29
  "axios": "^0.27.2",
30
30
  "bignumber.js": "^9.0.2",
31
31
  "parse-uri": "^1.0.7",
@@ -35,5 +35,5 @@
35
35
  "@types/parse-uri": "^1.0.0",
36
36
  "@types/semver": "^7.3.9"
37
37
  },
38
- "gitHead": "edfa30382fdf36182bc389c8ff1dd1a689096592"
38
+ "gitHead": "d50dc424865150391b7249d1010ee75dc2074a7e"
39
39
  }
@@ -1,6 +1,8 @@
1
1
  import { UI_REQUEST } from '../constants/ui-request';
2
2
  import { Device } from '../device/Device';
3
3
  import DeviceConnector from '../device/DeviceConnector';
4
+ import { DeviceFirmwareRange } from '../types';
5
+ import { CoreMessage } from '../events';
4
6
 
5
7
  export abstract class BaseMethod<Params = undefined> {
6
8
  responseID: number;
@@ -47,6 +49,9 @@ export abstract class BaseMethod<Params = undefined> {
47
49
  */
48
50
  requireDeviceMode: string[];
49
51
 
52
+ // @ts-expect-error: strictPropertyInitialization
53
+ postMessage: (message: CoreMessage) => void;
54
+
50
55
  constructor(message: { id?: number; payload: any }) {
51
56
  const { payload } = message;
52
57
  this.name = payload.method;
@@ -62,6 +67,10 @@ export abstract class BaseMethod<Params = undefined> {
62
67
 
63
68
  abstract run(): Promise<any>;
64
69
 
70
+ getVersionRange(): DeviceFirmwareRange {
71
+ return {};
72
+ }
73
+
65
74
  setDevice(device: Device) {
66
75
  this.device = device;
67
76
  this.connectId = device.originalDescriptor.path;
@@ -0,0 +1,66 @@
1
+ import { CipherKeyValue as HardwareCipherKeyValue } from '@onekeyfe/hd-transport/src/types/messages';
2
+ import { UI_REQUEST } from '../constants/ui-request';
3
+ import { serializedPath, validatePath } from './helpers/pathUtils';
4
+ import { BaseMethod } from './BaseMethod';
5
+ import { validateParams } from './helpers/paramsValidator';
6
+ import { CipheredKeyValue, CipheredKeyValueParams } from '../types';
7
+ import { formatAnyHex } from './helpers/hexUtils';
8
+
9
+ export default class CipherKeyValue extends BaseMethod<HardwareCipherKeyValue[]> {
10
+ hasBundle = false;
11
+
12
+ init() {
13
+ this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.INITIALIZE];
14
+
15
+ this.hasBundle = !!this.payload?.bundle;
16
+ const payload = this.hasBundle ? this.payload : { bundle: [this.payload] };
17
+
18
+ // check payload
19
+ validateParams(payload, [{ name: 'bundle', type: 'array' }]);
20
+
21
+ // init params
22
+ this.params = [];
23
+ payload.bundle.forEach((batch: CipheredKeyValueParams) => {
24
+ const addressN = validatePath(batch.path);
25
+
26
+ validateParams(batch, [
27
+ { name: 'path', required: true },
28
+ { name: 'key', type: 'string' },
29
+ { name: 'value', type: 'hexString' },
30
+ { name: 'encrypt', type: 'boolean' },
31
+ { name: 'askOnEncrypt', type: 'boolean' },
32
+ { name: 'askOnDecrypt', type: 'boolean' },
33
+ { name: 'iv', type: 'hexString' },
34
+ ]);
35
+
36
+ this.params.push({
37
+ address_n: addressN,
38
+ key: batch.key,
39
+ value: formatAnyHex(batch.value),
40
+ encrypt: batch.encrypt,
41
+ ask_on_encrypt: batch.askOnEncrypt,
42
+ ask_on_decrypt: batch.askOnDecrypt,
43
+ iv: formatAnyHex(batch.iv),
44
+ });
45
+ });
46
+ }
47
+
48
+ async run() {
49
+ const responses: CipheredKeyValue[] = [];
50
+
51
+ for (let i = 0; i < this.params.length; i++) {
52
+ const param = this.params[i];
53
+
54
+ const res = await this.device.commands.typedCall('CipherKeyValue', 'CipheredKeyValue', {
55
+ ...param,
56
+ });
57
+
58
+ responses.push({
59
+ path: serializedPath(param.address_n),
60
+ ...res.message,
61
+ });
62
+ }
63
+
64
+ return Promise.resolve(this.hasBundle ? responses : responses[0]);
65
+ }
66
+ }
@@ -0,0 +1,78 @@
1
+ import { ERRORS } from '../constants';
2
+ import { UI_REQUEST } from '../constants/ui-request';
3
+ import { BaseMethod } from './BaseMethod';
4
+ import { validateParams } from './helpers/paramsValidator';
5
+ import { getBinary } from './firmware/getBinary';
6
+ import { uploadFirmware } from './firmware/uploadFirmware';
7
+
8
+ type Params = {
9
+ binary?: ArrayBuffer;
10
+ version?: number[];
11
+ updateType: 'firmware' | 'ble';
12
+ };
13
+
14
+ export default class FirmwareUpdate extends BaseMethod<Params> {
15
+ init() {
16
+ this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.INITIALIZE];
17
+ this.requireDeviceMode = [UI_REQUEST.BOOTLOADER];
18
+
19
+ const { payload } = this;
20
+
21
+ validateParams(payload, [
22
+ { name: 'version', type: 'array' },
23
+ { name: 'binary', type: 'buffer' },
24
+ ]);
25
+
26
+ if (!payload.updateType) {
27
+ throw ERRORS.TypedError('Method_InvalidParameter', 'updateType is required');
28
+ }
29
+
30
+ this.params = { updateType: payload.updateType };
31
+
32
+ if ('version' in payload) {
33
+ this.params = {
34
+ ...this.params,
35
+ version: payload.version,
36
+ };
37
+ }
38
+
39
+ if ('binary' in payload) {
40
+ this.params = {
41
+ ...this.params,
42
+ binary: payload.binary,
43
+ };
44
+ }
45
+ }
46
+
47
+ async run() {
48
+ const { device, params } = this;
49
+
50
+ let binary;
51
+
52
+ try {
53
+ if (params.binary) {
54
+ binary = this.params.binary;
55
+ } else {
56
+ if (!device.features) {
57
+ throw ERRORS.TypedError('Runtime', 'no features found for this device');
58
+ }
59
+ const firmware = await getBinary({
60
+ features: device.features,
61
+ version: params.version,
62
+ updateType: params.updateType,
63
+ });
64
+ binary = firmware.binary;
65
+ }
66
+ } catch (err) {
67
+ throw ERRORS.TypedError('Method_FirmwareUpdate_DownloadFailed', err);
68
+ }
69
+
70
+ return uploadFirmware(
71
+ params.updateType,
72
+ this.device.getCommands().typedCall.bind(this.device.getCommands()),
73
+ this.postMessage,
74
+ device,
75
+ { payload: binary }
76
+ );
77
+ }
78
+ }
@@ -5,6 +5,17 @@ import { BaseMethod } from '../BaseMethod';
5
5
  export default class DeviceRebootToBootloader extends BaseMethod<RebootToBootloader> {
6
6
  init() {}
7
7
 
8
+ getVersionRange() {
9
+ return {
10
+ classic: {
11
+ min: '2.1.11',
12
+ },
13
+ mini: {
14
+ min: '2.1.11',
15
+ },
16
+ };
17
+ }
18
+
8
19
  async run() {
9
20
  const res = await this.device.commands.typedCall('RebootToBootloader', 'Success');
10
21
 
@@ -26,6 +26,14 @@ export default class EVMSignMessageEIP712 extends BaseMethod<EthereumSignMessage
26
26
  };
27
27
  }
28
28
 
29
+ getVersionRange() {
30
+ return {
31
+ model_mini: {
32
+ min: '2.1.9',
33
+ },
34
+ };
35
+ }
36
+
29
37
  async run() {
30
38
  const res = await this.device.commands.typedCall(
31
39
  'EthereumSignMessageEIP712',
@@ -178,6 +178,21 @@ export default class EVMSignTransaction extends BaseMethod {
178
178
  return this.processTxRequest(response.message, rest, chainId);
179
179
  };
180
180
 
181
+ getVersionRange() {
182
+ if (this.isEIP1559) {
183
+ return {
184
+ model_mini: {
185
+ min: '2.1.11',
186
+ },
187
+ };
188
+ }
189
+ return {
190
+ model_mini: {
191
+ min: '1.0.0',
192
+ },
193
+ };
194
+ }
195
+
181
196
  async run() {
182
197
  const { addressN, isEIP1559, formattedTx } = this;
183
198
 
@@ -1,4 +1,6 @@
1
+ import semver from 'semver';
1
2
  import {
3
+ EthereumMessageSignature,
2
4
  EthereumTypedDataSignature,
3
5
  EthereumTypedDataStructAck,
4
6
  MessageKey,
@@ -14,6 +16,8 @@ import {
14
16
  EthereumSignTypedDataMessage,
15
17
  EthereumSignTypedDataTypes,
16
18
  } from '../../types/api/evmSignTypedData';
19
+ import { getDeviceFirmwareVersion, getDeviceType } from '../../utils/deviceFeaturesUtils';
20
+ import { TypedResponseMessage } from '../../device/DeviceCommands';
17
21
 
18
22
  export type EVMSignTypedDataParams = {
19
23
  addressN: number[];
@@ -23,14 +27,14 @@ export type EVMSignTypedDataParams = {
23
27
  messageHash?: string;
24
28
  };
25
29
 
26
- export default class EVMSignMessageEIP712 extends BaseMethod<EVMSignTypedDataParams> {
30
+ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams> {
27
31
  init() {
28
32
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.INITIALIZE];
29
33
 
30
34
  validateParams(this.payload, [
31
35
  { name: 'path', required: true },
32
- { name: 'metamaskV4Compat', type: 'boolean', required: true },
33
- { name: 'data', type: 'object', required: true },
36
+ { name: 'metamaskV4Compat', type: 'boolean' },
37
+ { name: 'data', type: 'object' },
34
38
  { name: 'domainHash', type: 'hexString' },
35
39
  { name: 'messageHash', type: 'hexString' },
36
40
  ]);
@@ -49,7 +53,7 @@ export default class EVMSignMessageEIP712 extends BaseMethod<EVMSignTypedDataPar
49
53
  this.params.domainHash = formatAnyHex(domainHash);
50
54
  if (messageHash) {
51
55
  this.params.messageHash = formatAnyHex(messageHash);
52
- } else if (!data.primaryType || data.primaryType !== 'EIP712Domain') {
56
+ } else if (!!data && (!data.primaryType || data.primaryType !== 'EIP712Domain')) {
53
57
  throw ERRORS.TypedError(
54
58
  'Method_InvalidParameter',
55
59
  'message_hash should only be empty when data.primaryType=EIP712Domain'
@@ -173,6 +177,28 @@ export default class EVMSignMessageEIP712 extends BaseMethod<EVMSignTypedDataPar
173
177
  // };
174
178
  // }
175
179
 
180
+ getVersionRange() {
181
+ return {
182
+ model_mini: {
183
+ min: '2.1.9',
184
+ },
185
+ };
186
+ }
187
+
188
+ supportSignTyped() {
189
+ const deviceType = getDeviceType(this.device.features);
190
+ if (deviceType === 'classic' || deviceType === 'mini') {
191
+ const currentVersion = getDeviceFirmwareVersion(this.device.features).join('.');
192
+ const supportSignTypedVersion = '2.2.0';
193
+
194
+ if (semver.lt(currentVersion, supportSignTypedVersion)) {
195
+ return false;
196
+ }
197
+ }
198
+
199
+ return true;
200
+ }
201
+
176
202
  async run() {
177
203
  if (!this.device.features) {
178
204
  throw ERRORS.TypedError(
@@ -184,23 +210,37 @@ export default class EVMSignMessageEIP712 extends BaseMethod<EVMSignTypedDataPar
184
210
  const { addressN } = this.params;
185
211
 
186
212
  // For Classic、Mini device we use EthereumSignTypedData
187
- if (this.device.features.model === '1') {
213
+ const deviceType = getDeviceType(this.device.features);
214
+ if (deviceType === 'classic' || deviceType === 'mini') {
188
215
  validateParams(this.params, [
189
216
  { name: 'domainHash', type: 'hexString', required: true },
190
- { name: 'messageHash', type: 'hexString' },
217
+ { name: 'messageHash', type: 'hexString', required: true },
191
218
  ]);
192
219
 
193
220
  const { domainHash, messageHash } = this.params;
194
221
 
195
- const response = await this.device.commands.typedCall(
196
- 'EthereumSignTypedHash',
197
- 'EthereumTypedDataSignature',
198
- {
199
- address_n: addressN,
200
- domain_separator_hash: domainHash ?? '',
201
- message_hash: messageHash,
202
- }
203
- );
222
+ let response;
223
+ if (this.supportSignTyped()) {
224
+ response = await this.device.commands.typedCall(
225
+ 'EthereumSignTypedHash',
226
+ 'EthereumTypedDataSignature',
227
+ {
228
+ address_n: addressN,
229
+ domain_separator_hash: domainHash ?? '',
230
+ message_hash: messageHash,
231
+ }
232
+ );
233
+ } else {
234
+ response = await this.device.commands.typedCall(
235
+ 'EthereumSignMessageEIP712',
236
+ 'EthereumMessageSignature',
237
+ {
238
+ address_n: addressN,
239
+ domain_hash: domainHash ?? '',
240
+ message_hash: messageHash ?? '',
241
+ }
242
+ );
243
+ }
204
244
 
205
245
  return Promise.resolve(response.message);
206
246
  }
@@ -0,0 +1,46 @@
1
+ import semver from 'semver';
2
+ import { Features } from '../../types';
3
+ import { getDeviceType, httpRequest } from '../../utils';
4
+ import { DataManager } from '../../data-manager';
5
+ import { ERRORS } from '../../constants';
6
+
7
+ export interface GetInfoProps {
8
+ features: Features;
9
+ updateType: 'firmware' | 'ble';
10
+ }
11
+
12
+ interface GetBinaryProps extends GetInfoProps {
13
+ version?: number[];
14
+ }
15
+
16
+ export const getBinary = async ({ features, updateType, version }: GetBinaryProps) => {
17
+ const releaseInfo = getInfo({ features, updateType });
18
+
19
+ if (!releaseInfo) {
20
+ throw ERRORS.TypedError('Runtime', 'no firmware found for this device');
21
+ }
22
+
23
+ if (
24
+ version &&
25
+ !semver.eq(releaseInfo.version as unknown as semver.SemVer, version as unknown as semver.SemVer)
26
+ ) {
27
+ throw ERRORS.TypedError('Runtime', 'firmware version mismatch');
28
+ }
29
+
30
+ // @ts-expect-error
31
+ const url = updateType === 'ble' ? releaseInfo.webUpdate : releaseInfo.url;
32
+ const fw = await httpRequest(url, 'binary');
33
+
34
+ return {
35
+ ...releaseInfo,
36
+ binary: fw,
37
+ };
38
+ };
39
+
40
+ const getInfo = ({ features, updateType }: GetInfoProps) => {
41
+ const deviceType = getDeviceType(features);
42
+ const { deviceMap } = DataManager;
43
+ const releaseInfo = deviceMap?.[deviceType]?.[updateType]?.[0] ?? null;
44
+
45
+ return releaseInfo;
46
+ };
@@ -0,0 +1,72 @@
1
+ import { DEVICE, CoreMessage, createUiMessage, UI_REQUEST } from '../../events';
2
+ import { ERRORS, PROTO } from '../../constants';
3
+ import type { Device } from '../../device/Device';
4
+ import type { TypedCall } from '../../device/DeviceCommands';
5
+ import { KnownDevice } from '../../types';
6
+
7
+ const postConfirmationMessage = (device: Device) => {
8
+ // only if firmware is already installed. fresh device does not require button confirmation
9
+ if (device.features?.firmware_present) {
10
+ device.emit(DEVICE.BUTTON, device, { code: 'ButtonRequest_FirmwareUpdate' });
11
+ }
12
+ };
13
+
14
+ const postProgressMessage = (
15
+ device: Device,
16
+ progress: number,
17
+ postMessage: (message: CoreMessage) => void
18
+ ) => {
19
+ postMessage(
20
+ createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
21
+ device: device.toMessageObject() as KnownDevice,
22
+ progress,
23
+ })
24
+ );
25
+ };
26
+
27
+ export const uploadFirmware = async (
28
+ updateType: 'firmware' | 'ble',
29
+ typedCall: TypedCall,
30
+ postMessage: (message: CoreMessage) => void,
31
+ device: Device,
32
+ { payload }: PROTO.FirmwareUpload
33
+ ) => {
34
+ if (device.features?.major_version === 1) {
35
+ postConfirmationMessage(device);
36
+ const eraseCommand = updateType === 'firmware' ? 'FirmwareErase' : 'FirmwareErase_ex';
37
+ await typedCall(eraseCommand as unknown as any, 'Success', {});
38
+ postProgressMessage(device, 0, postMessage);
39
+ const { message } = await typedCall('FirmwareUpload', 'Success', {
40
+ payload,
41
+ });
42
+
43
+ return message;
44
+ }
45
+
46
+ if (device.features?.major_version === 2) {
47
+ postConfirmationMessage(device);
48
+ const length = payload.byteLength;
49
+
50
+ let response = await typedCall('FirmwareErase', ['FirmwareRequest', 'Success'], { length });
51
+ while (response.type !== 'Success') {
52
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
53
+ const start = response.message.offset!;
54
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
55
+ const end = response.message.offset! + response.message.length!;
56
+ const chunk = payload.slice(start, end);
57
+
58
+ if (start > 0) {
59
+ postProgressMessage(device, Math.round((start / length) * 100), postMessage);
60
+ }
61
+
62
+ response = await typedCall('FirmwareUpload', ['FirmwareRequest', 'Success'], {
63
+ payload: chunk,
64
+ });
65
+ }
66
+
67
+ postProgressMessage(device, 100, postMessage);
68
+ return response.message;
69
+ }
70
+
71
+ throw ERRORS.TypedError('Runtime', 'uploadFirmware: unknown major_version');
72
+ };
@@ -44,7 +44,6 @@ export const formatAnyHex: (value: any) => any = value => {
44
44
  if (typeof value === 'object') {
45
45
  return modifyValues(value, value => formatAnyHex(value));
46
46
  }
47
- console.log('unexpected value', value);
48
47
 
49
48
  return value;
50
49
  };
package/src/api/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { default as searchDevices } from './SearchDevices';
2
2
  export { default as getFeatures } from './GetFeatures';
3
+ export { default as cipherKeyValue } from './CipherKeyValue';
3
4
  export { default as btcGetAddress } from './btc/BTCGetAddress';
4
5
  export { default as btcGetPublicKey } from './btc/BTCGetPublicKey';
5
6
  export { default as btcSignMessage } from './btc/BTCSignMessage';
@@ -29,3 +30,14 @@ export { default as starcoinGetPublicKey } from './starcoin/StarcoinGetPublicKey
29
30
  export { default as starcoinSignMessage } from './starcoin/StarcoinSignMessage';
30
31
  export { default as starcoinSignTransaction } from './starcoin/StarcoinSignTransaction';
31
32
  export { default as starcoinVerifyMessage } from './starcoin/StarcoinVerifyMessage';
33
+
34
+ export { default as nemGetAddress } from './nem/NEMGetAddress';
35
+ export { default as nemSignTransaction } from './nem/NEMSignTransaction';
36
+
37
+ export { default as solGetAddress } from './solana/SolGetAddress';
38
+ export { default as solSignTransaction } from './solana/SolSignTransaction';
39
+
40
+ export { default as stellarGetAddress } from './stellar/StellarGetAddress';
41
+ export { default as stellarSignTransaction } from './stellar/StellarSignTransaction';
42
+
43
+ export { default as firmwareUpdate } from './FirmwareUpdate';
@@ -0,0 +1,61 @@
1
+ import { NEMGetAddress as HardwareNEMGetAddress } from '@onekeyfe/hd-transport/src/types/messages';
2
+ import { UI_REQUEST } from '../../constants/ui-request';
3
+ import { validatePath, serializedPath } from '../helpers/pathUtils';
4
+ import { BaseMethod } from '../BaseMethod';
5
+ import { validateParams } from '../helpers/paramsValidator';
6
+ import { NEMAddress, NEMGetAddressParams } from '../../types';
7
+
8
+ const MAINNET = 0x68; // 104
9
+
10
+ export default class NEMGetAddress extends BaseMethod<HardwareNEMGetAddress[]> {
11
+ hasBundle = false;
12
+
13
+ init() {
14
+ this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.INITIALIZE];
15
+
16
+ this.hasBundle = !!this.payload?.bundle;
17
+ const payload = this.hasBundle ? this.payload : { bundle: [this.payload] };
18
+
19
+ // check payload
20
+ validateParams(payload, [{ name: 'bundle', type: 'array' }]);
21
+
22
+ // init params
23
+ this.params = [];
24
+ payload.bundle.forEach((batch: NEMGetAddressParams) => {
25
+ const addressN = validatePath(batch.path, 3);
26
+
27
+ validateParams(batch, [
28
+ { name: 'path', required: true },
29
+ { name: 'network', type: 'number' },
30
+ { name: 'showOnOneKey', type: 'boolean' },
31
+ ]);
32
+
33
+ const showOnOneKey = batch.showOnOneKey ?? true;
34
+
35
+ this.params.push({
36
+ address_n: addressN,
37
+ network: batch.network || MAINNET,
38
+ show_display: showOnOneKey,
39
+ });
40
+ });
41
+ }
42
+
43
+ async run() {
44
+ const responses: NEMAddress[] = [];
45
+
46
+ for (let i = 0; i < this.params.length; i++) {
47
+ const param = this.params[i];
48
+
49
+ const res = await this.device.commands.typedCall('NEMGetAddress', 'NEMAddress', {
50
+ ...param,
51
+ });
52
+
53
+ responses.push({
54
+ path: serializedPath(param.address_n),
55
+ ...res.message,
56
+ });
57
+ }
58
+
59
+ return Promise.resolve(this.hasBundle ? responses : responses[0]);
60
+ }
61
+ }