@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.
- package/dist/api/BaseMethod.d.ts +4 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CipherKeyValue.d.ts +9 -0
- package/dist/api/CipherKeyValue.d.ts.map +1 -0
- package/dist/api/FirmwareUpdate.d.ts +14 -0
- package/dist/api/FirmwareUpdate.d.ts.map +1 -0
- package/dist/api/device/DeviceRebootToBootloader.d.ts +8 -0
- package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
- package/dist/api/evm/EVMSignMessageEIP712.d.ts +5 -0
- package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTransaction.d.ts +5 -0
- package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts +7 -1
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +33 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -0
- package/dist/api/firmware/uploadFirmware.d.ts +8 -0
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -0
- package/dist/api/helpers/hexUtils.d.ts.map +1 -1
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/nem/NEMGetAddress.d.ts +9 -0
- package/dist/api/nem/NEMGetAddress.d.ts.map +1 -0
- package/dist/api/nem/NEMSignTransaction.d.ts +20 -0
- package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -0
- package/dist/api/solana/SolGetAddress.d.ts +9 -0
- package/dist/api/solana/SolGetAddress.d.ts.map +1 -0
- package/dist/api/solana/SolSignTransaction.d.ts +17 -0
- package/dist/api/solana/SolSignTransaction.d.ts.map +1 -0
- package/dist/api/stellar/StellarGetAddress.d.ts +9 -0
- package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -0
- package/dist/api/stellar/StellarSignTransaction.d.ts +335 -0
- package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -0
- package/dist/constants/errors.d.ts +1 -0
- package/dist/constants/errors.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data/version.d.ts +1 -1
- package/dist/data/version.d.ts.map +1 -1
- package/dist/device/Device.d.ts +1 -0
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +1 -0
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +9 -1
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +364 -5
- package/dist/index.js +845 -21
- package/dist/inject.d.ts.map +1 -1
- package/dist/types/api/cipherKeyValue.d.ts +19 -0
- package/dist/types/api/cipherKeyValue.d.ts.map +1 -0
- package/dist/types/api/export.d.ts +7 -0
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +13 -0
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +16 -0
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/nemGetAddress.d.ts +15 -0
- package/dist/types/api/nemGetAddress.d.ts.map +1 -0
- package/dist/types/api/nemSignTransaction.d.ts +93 -0
- package/dist/types/api/nemSignTransaction.d.ts.map +1 -0
- package/dist/types/api/solGetAddress.d.ts +14 -0
- package/dist/types/api/solGetAddress.d.ts.map +1 -0
- package/dist/types/api/solSignTransaction.d.ts +14 -0
- package/dist/types/api/solSignTransaction.d.ts.map +1 -0
- package/dist/types/api/stellarGetAddress.d.ts +14 -0
- package/dist/types/api/stellarGetAddress.d.ts.map +1 -0
- package/dist/types/api/stellarSignTransaction.d.ts +130 -0
- package/dist/types/api/stellarSignTransaction.d.ts.map +1 -0
- package/dist/types/device.d.ts +45 -0
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/firmware.d.ts +2 -1
- package/dist/types/firmware.d.ts.map +1 -1
- package/dist/types/params.d.ts +3 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/utils/assets.d.ts +1 -1
- package/dist/utils/assets.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +49 -2
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/networkUtils.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/api/BaseMethod.ts +9 -0
- package/src/api/CipherKeyValue.ts +66 -0
- package/src/api/FirmwareUpdate.ts +78 -0
- package/src/api/device/DeviceRebootToBootloader.ts +11 -0
- package/src/api/evm/EVMSignMessageEIP712.ts +8 -0
- package/src/api/evm/EVMSignTransaction.ts +15 -0
- package/src/api/evm/EVMSignTypedData.ts +55 -15
- package/src/api/firmware/getBinary.ts +46 -0
- package/src/api/firmware/uploadFirmware.ts +72 -0
- package/src/api/helpers/hexUtils.ts +0 -1
- package/src/api/index.ts +12 -0
- package/src/api/nem/NEMGetAddress.ts +61 -0
- package/src/api/nem/NEMSignTransaction.ts +246 -0
- package/src/api/solana/SolGetAddress.ts +59 -0
- package/src/api/solana/SolSignTransaction.ts +69 -0
- package/src/api/stellar/StellarGetAddress.ts +59 -0
- package/src/api/stellar/StellarSignTransaction.ts +213 -0
- package/src/constants/errors.ts +1 -0
- package/src/core/index.ts +40 -5
- package/src/data/version.ts +1 -1
- package/src/device/Device.ts +4 -0
- package/src/device/DeviceCommands.ts +2 -0
- package/src/events/ui-request.ts +15 -1
- package/src/inject.ts +17 -0
- package/src/types/api/cipherKeyValue.ts +26 -0
- package/src/types/api/export.ts +27 -0
- package/src/types/api/firmwareUpdate.ts +21 -0
- package/src/types/api/index.ts +21 -0
- package/src/types/api/nemGetAddress.ts +22 -0
- package/src/types/api/nemSignTransaction.ts +117 -0
- package/src/types/api/solGetAddress.ts +21 -0
- package/src/types/api/solSignTransaction.ts +21 -0
- package/src/types/api/stellarGetAddress.ts +21 -0
- package/src/types/api/stellarSignTransaction.ts +153 -0
- package/src/types/device.ts +52 -0
- package/src/types/firmware.ts +2 -1
- package/src/types/params.ts +2 -0
- package/src/utils/assets.ts +1 -1
- package/src/utils/deviceFeaturesUtils.ts +16 -2
- 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,
|
|
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
|
|
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
|
|
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": "
|
|
38
|
+
"gitHead": "d50dc424865150391b7249d1010ee75dc2074a7e"
|
|
39
39
|
}
|
package/src/api/BaseMethod.ts
CHANGED
|
@@ -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
|
|
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'
|
|
33
|
-
{ name: 'data', type: 'object'
|
|
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
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
+
};
|
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
|
+
}
|