Skip to content

Commit d10c144

Browse files
committed
feat: optimize version limit
1 parent 5d8e461 commit d10c144

13 files changed

+91
-46
lines changed

packages/core/src/api/BaseMethod.ts

+50-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import semver from 'semver';
2+
import { ERRORS, HardwareError, HardwareErrorCode } from '@onekeyfe/hd-shared';
13
import { supportInputPinOnSoftware, supportModifyHomescreen } from '../utils/deviceFeaturesUtils';
24
import { createDeviceMessage } from '../events/device';
35
import { UI_REQUEST } from '../constants/ui-request';
@@ -6,7 +8,8 @@ import DeviceConnector from '../device/DeviceConnector';
68
import { DeviceFirmwareRange, KnownDevice } from '../types';
79
import { CoreMessage, createFirmwareMessage, createUiMessage, DEVICE, FIRMWARE } from '../events';
810
import { getBleFirmwareReleaseInfo, getFirmwareReleaseInfo } from './firmware/releaseHelper';
9-
import { getLogger, LoggerNames } from '../utils';
11+
import { getDeviceFirmwareVersion, getLogger, getMethodVersionRange, LoggerNames } from '../utils';
12+
import { DataManager } from '../data-manager';
1013

1114
const Log = getLogger(LoggerNames.Method);
1215

@@ -81,6 +84,12 @@ export abstract class BaseMethod<Params = undefined> {
8184
*/
8285
skipForceUpdateCheck = false;
8386

87+
/**
88+
* 是否需要预先检查版本限制
89+
* @default false
90+
*/
91+
preCheckVersionLimit = false;
92+
8493
// @ts-expect-error: strictPropertyInitialization
8594
postMessage: (message: CoreMessage) => void;
8695

@@ -127,6 +136,46 @@ export abstract class BaseMethod<Params = undefined> {
127136
);
128137
}
129138

139+
handleUnsupportedMethodError(error: HardwareError) {
140+
if (!error.message.includes('Failure_UnexpectedMessage')) {
141+
return undefined;
142+
}
143+
144+
const versionRange = getMethodVersionRange(
145+
this.device.features,
146+
type => this.getVersionRange()[type]
147+
);
148+
149+
if (!versionRange || !this.device.features) {
150+
return ERRORS.TypedError(HardwareErrorCode.UnsupportedMethod);
151+
}
152+
const newVersionStatus = DataManager.getFirmwareStatus(this.device.features);
153+
const currentVersion = getDeviceFirmwareVersion(this.device.features).join('.');
154+
if (semver.valid(versionRange.min) && semver.lt(currentVersion, versionRange.min)) {
155+
if (newVersionStatus === 'none' || newVersionStatus === 'valid') {
156+
throw ERRORS.TypedError(HardwareErrorCode.NewFirmwareUnRelease);
157+
}
158+
159+
return ERRORS.TypedError(
160+
HardwareErrorCode.CallMethodNeedUpgradeFirmware,
161+
`Device firmware version is too low, please update to ${versionRange.min}`,
162+
{ current: currentVersion, require: versionRange.min }
163+
);
164+
}
165+
166+
if (
167+
versionRange.max &&
168+
semver.valid(versionRange.max) &&
169+
semver.gte(currentVersion, versionRange.max)
170+
) {
171+
return ERRORS.TypedError(
172+
HardwareErrorCode.CallMethodDeprecated,
173+
`Device firmware version is too high, this method has been deprecated in ${versionRange.max}`,
174+
{ current: currentVersion, deprecated: versionRange.max }
175+
);
176+
}
177+
}
178+
130179
checkDeviceSupportFeature() {
131180
if (!this.device || !this.device.features) return;
132181
const inputPinOnSoftware = supportInputPinOnSoftware(this.device.features);

packages/core/src/api/btc/BTCGetAddress.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { getBitcoinForkVersionRange } from './helpers/versionLimit';
1010
export default class BTCGetAddress extends BaseMethod<GetAddress[]> {
1111
hasBundle = false;
1212

13+
preCheckVersionLimit = true;
14+
1315
init() {
1416
this.checkDeviceId = true;
1517
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

packages/core/src/api/btc/BTCGetPublicKey.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { getBitcoinForkVersionRange } from './helpers/versionLimit';
1111
export default class BTCGetPublicKey extends BaseMethod<GetPublicKey[]> {
1212
hasBundle = false;
1313

14+
preCheckVersionLimit = true;
15+
1416
init() {
1517
this.checkDeviceId = true;
1618
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

packages/core/src/api/btc/BTCSignMessage.ts

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { getCoinAndScriptType } from './helpers/btcParamsUtils';
88
import { getBitcoinForkVersionRange } from './helpers/versionLimit';
99

1010
export default class BTCSignMessage extends BaseMethod<SignMessage> {
11+
preCheckVersionLimit = true;
12+
1113
init() {
1214
this.checkDeviceId = true;
1315
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

packages/core/src/api/btc/BTCSignPsbt.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { formatAnyHex } from '../helpers/hexUtils';
66
import { getCoinInfo } from './helpers/btcParamsUtils';
77

88
export default class BTCSignPsbt extends BaseMethod<SignPsbt> {
9+
preCheckVersionLimit = true;
10+
911
init() {
1012
this.checkDeviceId = true;
1113
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

packages/core/src/api/btc/BTCSignTransaction.ts

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type Params = {
2525
coinName: string;
2626
};
2727
export default class BTCSignTransaction extends BaseMethod<Params> {
28+
preCheckVersionLimit = true;
29+
2830
init() {
2931
this.checkDeviceId = true;
3032
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

packages/core/src/api/btc/BTCVerifyMessage.ts

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import { getCoinInfo } from './helpers/btcParamsUtils';
88
import { getBitcoinForkVersionRange } from './helpers/versionLimit';
99

1010
export default class BTCVerifyMessage extends BaseMethod<VerifyMessage> {
11+
preCheckVersionLimit = true;
12+
1113
init() {
1214
this.checkDeviceId = true;
1315
this.notAllowDeviceMode = [...this.notAllowDeviceMode, UI_REQUEST.INITIALIZE];

packages/core/src/api/evm/EVMSignTransaction.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { signTransaction } from './latest/signTransaction';
1010
import { signTransaction as signTransactionLegacyV1 } from './legacyV1/signTransaction';
1111

1212
export default class EVMSignTransaction extends BaseMethod {
13+
preCheckVersionLimit = true;
14+
1315
addressN: number[] = [];
1416

1517
isEIP1559 = false;

packages/core/src/api/polkadot/PolkadotGetAddress.ts

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { getPolkadotVersionRangeWithBundle } from './networks';
99
export default class PolkadotGetAddress extends BaseMethod<HardwarePolkadotGetAddress[]> {
1010
hasBundle = false;
1111

12+
preCheckVersionLimit = true;
13+
1214
init() {
1315
this.checkDeviceId = true;
1416
this.notAllowDeviceMode = [...this.notAllowDeviceMode];

packages/core/src/api/polkadot/PolkadotSignTransaction.ts

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { getPolkadotVersionRange } from './networks';
99
export default class PolkadotSignTransaction extends BaseMethod<HardwarePolkadotSignTx> {
1010
hasBundle = false;
1111

12+
preCheckVersionLimit = true;
13+
1214
init() {
1315
this.checkDeviceId = true;
1416
this.notAllowDeviceMode = [...this.notAllowDeviceMode];

packages/core/src/api/solana/SolSignTransaction.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { SolanaSignedTx, SolanaSignTransactionParams } from '../../types';
77
import { formatAnyHex } from '../helpers/hexUtils';
88

99
export default class SolSignTransaction extends BaseMethod<HardwareSolanaSignTx[]> {
10+
preCheckVersionLimit = true;
11+
1012
hasBundle = false;
1113

1214
init() {

packages/core/src/core/index.ts

+15-44
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import semver from 'semver';
21
import EventEmitter from 'events';
32
import { Features, LowlevelTransportSharedPlugin, OneKeyDeviceInfo } from '@onekeyfe/hd-transport';
43
import {
@@ -8,15 +7,7 @@ import {
87
HardwareError,
98
HardwareErrorCode,
109
} from '@onekeyfe/hd-shared';
11-
import {
12-
getDeviceFirmwareVersion,
13-
enableLog,
14-
getLogger,
15-
LoggerNames,
16-
setLoggerPostMessage,
17-
wait,
18-
getMethodVersionRange,
19-
} from '../utils';
10+
import { enableLog, getLogger, LoggerNames, setLoggerPostMessage, wait } from '../utils';
2011
import { supportNewPassphrase } from '../utils/deviceFeaturesUtils';
2112
import { Device, DeviceEvents, InitOptions, RunOptions } from '../device/Device';
2213
import { DeviceList } from '../device/DeviceList';
@@ -108,7 +99,10 @@ export const callAPI = async (message: CoreMessage) => {
10899
const response = await method.run();
109100
return createResponseMessage(method.responseID, true, response);
110101
} catch (error) {
111-
return createResponseMessage(method.responseID, false, { error });
102+
const unsupportedMethodError = method.handleUnsupportedMethodError(error);
103+
return createResponseMessage(method.responseID, false, {
104+
error: unsupportedMethodError ?? error,
105+
});
112106
}
113107
}
114108

@@ -162,11 +156,6 @@ export const callAPI = async (message: CoreMessage) => {
162156
try {
163157
const inner = async (): Promise<void> => {
164158
// check firmware version
165-
const versionRange = getMethodVersionRange(
166-
device.features,
167-
type => method.getVersionRange()[type]
168-
);
169-
170159
if (device.features) {
171160
await DataManager.checkAndReloadData();
172161
const newVersionStatus = DataManager.getFirmwareStatus(device.features);
@@ -182,33 +171,12 @@ export const callAPI = async (message: CoreMessage) => {
182171
);
183172
}
184173

185-
if (versionRange) {
186-
const currentVersion = getDeviceFirmwareVersion(device.features).join('.');
187-
if (semver.valid(versionRange.min) && semver.lt(currentVersion, versionRange.min)) {
188-
if (newVersionStatus === 'none' || newVersionStatus === 'valid') {
189-
throw ERRORS.TypedError(HardwareErrorCode.NewFirmwareUnRelease);
190-
}
191-
192-
return Promise.reject(
193-
ERRORS.TypedError(
194-
HardwareErrorCode.CallMethodNeedUpgradeFirmware,
195-
`Device firmware version is too low, please update to ${versionRange.min}`,
196-
{ current: currentVersion, require: versionRange.min }
197-
)
198-
);
199-
}
200-
if (
201-
versionRange.max &&
202-
semver.valid(versionRange.max) &&
203-
semver.gte(currentVersion, versionRange.max)
204-
) {
205-
return Promise.reject(
206-
ERRORS.TypedError(
207-
HardwareErrorCode.CallMethodDeprecated,
208-
`Device firmware version is too high, this method has been deprecated in ${versionRange.max}`,
209-
{ current: currentVersion, deprecated: versionRange.max }
210-
)
211-
);
174+
if (method.preCheckVersionLimit) {
175+
const error = method.handleUnsupportedMethodError(
176+
ERRORS.TypedError(HardwareErrorCode.UnknownError, 'Failure_UnexpectedMessage')
177+
);
178+
if (error) {
179+
throw error;
212180
}
213181
}
214182
}
@@ -306,7 +274,10 @@ export const callAPI = async (message: CoreMessage) => {
306274
_callPromise?.resolve(messageResponse);
307275
} catch (error) {
308276
Log.debug('Call API - Inner Method Run Error: ', error);
309-
messageResponse = createResponseMessage(method.responseID, false, { error });
277+
const unsupportedMethodError = method.handleUnsupportedMethodError(error);
278+
messageResponse = createResponseMessage(method.responseID, false, {
279+
error: unsupportedMethodError ?? error,
280+
});
310281
_callPromise?.resolve(messageResponse);
311282
}
312283
};

packages/shared/src/HardwareError.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ export const HardwareErrorCode = {
363363
*/
364364
BridgeDeviceDisconnected: 817,
365365

366+
/**
367+
* Unsupported Method
368+
*/
369+
UnsupportedMethod: 818,
370+
366371
/**
367372
* Lowlevel transport connect error
368373
*/
@@ -480,7 +485,7 @@ export const HardwareErrorCodeMessage: HardwareErrorCodeMessageMapping = {
480485
[HardwareErrorCode.CheckDownloadFileError]: 'Check download file error',
481486
[HardwareErrorCode.NotInSigningMode]: 'not in signing mode',
482487
[HardwareErrorCode.DataOverload]: 'Params data overload',
483-
488+
[HardwareErrorCode.UnsupportedMethod]: 'Unsupported method',
484489
/**
485490
* Lowlevel transport
486491
*/

0 commit comments

Comments
 (0)