@onekeyfe/hd-core 1.1.19-alpha.0 → 1.1.19-alpha.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.
- package/dist/api/BaseMethod.d.ts +5 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -4
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/bootloaderHelper.d.ts +1 -1
- package/dist/api/firmware/bootloaderHelper.d.ts.map +1 -1
- package/dist/api/firmware/updateBootloader.d.ts +1 -1
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +5 -5
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/Device.d.ts +5 -2
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +8 -6
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/index.d.ts +51 -6
- package/dist/index.js +404 -76
- package/dist/types/device.d.ts +3 -0
- package/dist/types/device.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/tracing.d.ts +34 -0
- package/dist/utils/tracing.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +38 -1
- package/src/api/FirmwareUpdate.ts +2 -1
- package/src/api/FirmwareUpdateV2.ts +2 -1
- package/src/api/FirmwareUpdateV3.ts +2 -0
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +46 -15
- package/src/api/evm/EVMSignTypedData.ts +8 -2
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +16 -18
- package/src/api/firmware/bootloaderHelper.ts +3 -1
- package/src/api/firmware/updateBootloader.ts +6 -3
- package/src/api/firmware/uploadFirmware.ts +87 -21
- package/src/core/index.ts +135 -27
- package/src/data/messages/messages.json +11 -1
- package/src/device/Device.ts +24 -3
- package/src/device/DeviceCommands.ts +55 -13
- package/src/types/device.ts +5 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/logger.ts +3 -2
- package/src/utils/tracing.ts +238 -0
package/src/core/index.ts
CHANGED
|
@@ -1,62 +1,75 @@
|
|
|
1
1
|
import semver from 'semver';
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
|
-
import { Features, LowlevelTransportSharedPlugin, OneKeyDeviceInfo } from '@onekeyfe/hd-transport';
|
|
4
3
|
import {
|
|
5
|
-
createDeferred,
|
|
6
|
-
Deferred,
|
|
7
4
|
ERRORS,
|
|
8
5
|
HardwareError,
|
|
9
6
|
HardwareErrorCode,
|
|
7
|
+
createDefectiveFirmwareError,
|
|
8
|
+
createDeferred,
|
|
10
9
|
createDeprecatedHardwareError,
|
|
11
10
|
createNeedUpgradeFirmwareHardwareError,
|
|
12
11
|
createNewFirmwareForceUpdateHardwareError,
|
|
13
12
|
createNewFirmwareUnReleaseHardwareError,
|
|
14
|
-
createDefectiveFirmwareError,
|
|
15
13
|
} from '@onekeyfe/hd-shared';
|
|
14
|
+
|
|
16
15
|
import {
|
|
17
|
-
|
|
18
|
-
getDeviceBLEFirmwareVersion,
|
|
16
|
+
LoggerNames,
|
|
19
17
|
enableLog,
|
|
18
|
+
getDeviceBLEFirmwareVersion,
|
|
19
|
+
getDeviceFirmwareVersion,
|
|
20
|
+
getFirmwareType,
|
|
20
21
|
getLogger,
|
|
21
|
-
|
|
22
|
+
getMethodVersionRange,
|
|
22
23
|
setLoggerPostMessage,
|
|
23
24
|
wait,
|
|
24
|
-
getMethodVersionRange,
|
|
25
|
-
getFirmwareType,
|
|
26
25
|
} from '../utils';
|
|
27
26
|
import {
|
|
28
27
|
findDefectiveBatchDevice,
|
|
29
28
|
getDefectiveDeviceInfo,
|
|
30
29
|
} from '../utils/findDefectiveBatchDevice';
|
|
31
30
|
import { supportNewPassphrase } from '../utils/deviceFeaturesUtils';
|
|
32
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
cleanupSdkInstance,
|
|
33
|
+
completeRequestContext,
|
|
34
|
+
createRequestContext,
|
|
35
|
+
createSdkTracingContext,
|
|
36
|
+
formatRequestContext,
|
|
37
|
+
getActiveRequestsByDeviceInstance,
|
|
38
|
+
updateRequestContext,
|
|
39
|
+
} from '../utils/tracing';
|
|
40
|
+
import { Device } from '../device/Device';
|
|
33
41
|
import { DeviceList } from '../device/DeviceList';
|
|
34
42
|
import { DevicePool } from '../device/DevicePool';
|
|
35
43
|
import { findMethod } from '../api/utils';
|
|
36
44
|
import { DataManager } from '../data-manager';
|
|
37
|
-
|
|
38
45
|
import { UI_REQUEST as UI_REQUEST_CONST } from '../constants/ui-request';
|
|
39
46
|
import {
|
|
40
47
|
CORE_EVENT,
|
|
41
|
-
CoreMessage,
|
|
42
|
-
createDeviceMessage,
|
|
43
|
-
createResponseMessage,
|
|
44
|
-
createUiMessage,
|
|
45
48
|
DEVICE,
|
|
46
49
|
IFRAME,
|
|
47
|
-
IFrameCallMessage,
|
|
48
50
|
UI_REQUEST,
|
|
49
51
|
UI_RESPONSE,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
createDeviceMessage,
|
|
53
|
+
createResponseMessage,
|
|
54
|
+
createUiMessage,
|
|
52
55
|
} from '../events';
|
|
53
|
-
import type { BaseMethod } from '../api/BaseMethod';
|
|
54
|
-
import type { ConnectSettings, KnownDevice } from '../types';
|
|
55
56
|
import TransportManager from '../data-manager/TransportManager';
|
|
56
57
|
import DeviceConnector from '../device/DeviceConnector';
|
|
57
58
|
import RequestQueue from './RequestQueue';
|
|
58
59
|
import { getSynchronize } from '../utils/getSynchronize';
|
|
59
60
|
|
|
61
|
+
import type { ConnectSettings, KnownDevice } from '../types';
|
|
62
|
+
import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
|
|
63
|
+
import type { DeviceEvents, InitOptions, RunOptions } from '../device/Device';
|
|
64
|
+
import type { SdkTracingContext } from '../utils/tracing';
|
|
65
|
+
import type { Deferred } from '@onekeyfe/hd-shared';
|
|
66
|
+
import type {
|
|
67
|
+
Features,
|
|
68
|
+
LowlevelTransportSharedPlugin,
|
|
69
|
+
OneKeyDeviceInfo,
|
|
70
|
+
} from '@onekeyfe/hd-transport';
|
|
71
|
+
import type { BaseMethod } from '../api/BaseMethod';
|
|
72
|
+
|
|
60
73
|
const Log = getLogger(LoggerNames.Core);
|
|
61
74
|
|
|
62
75
|
export type CoreContext = ReturnType<Core['getCoreContext']>;
|
|
@@ -97,6 +110,30 @@ let preConnectCache: {
|
|
|
97
110
|
passphraseState: undefined,
|
|
98
111
|
};
|
|
99
112
|
|
|
113
|
+
const toError = (error: unknown): Error | undefined => {
|
|
114
|
+
if (error instanceof Error) return error;
|
|
115
|
+
if (error == null) return undefined;
|
|
116
|
+
if (typeof error === 'string') return new Error(error);
|
|
117
|
+
try {
|
|
118
|
+
return new Error(JSON.stringify(error));
|
|
119
|
+
} catch {
|
|
120
|
+
return new Error(String(error));
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const updateMethodRequestContext = (method: BaseMethod, updates: any) => {
|
|
125
|
+
if (method.requestContext) {
|
|
126
|
+
updateRequestContext(method.requestContext.responseID, updates);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const completeMethodRequestContext = (method: BaseMethod, error?: unknown) => {
|
|
131
|
+
if (!method.requestContext) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
completeRequestContext(method.requestContext.responseID, toError(error));
|
|
135
|
+
};
|
|
136
|
+
|
|
100
137
|
export const callAPI = async (context: CoreContext, message: CoreMessage) => {
|
|
101
138
|
if (!message.id || !message.payload || message.type !== IFRAME.CALL) {
|
|
102
139
|
return Promise.reject(ERRORS.TypedError('on call: message.id or message.payload is missing'));
|
|
@@ -108,6 +145,15 @@ export const callAPI = async (context: CoreContext, message: CoreMessage) => {
|
|
|
108
145
|
method = findMethod(message as IFrameCallMessage);
|
|
109
146
|
method.connector = _connector;
|
|
110
147
|
method.postMessage = postMessage;
|
|
148
|
+
method.setContext?.(context);
|
|
149
|
+
|
|
150
|
+
method.requestContext = createRequestContext(method.responseID, method.name, {
|
|
151
|
+
sdkInstanceId: context.sdkInstanceId,
|
|
152
|
+
connectId: method.connectId,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
Log.debug(`[${context.sdkInstanceId}] callAPI: ${formatRequestContext(method.requestContext)}`);
|
|
156
|
+
|
|
111
157
|
method.init();
|
|
112
158
|
} catch (error) {
|
|
113
159
|
return Promise.reject(error);
|
|
@@ -116,10 +162,13 @@ export const callAPI = async (context: CoreContext, message: CoreMessage) => {
|
|
|
116
162
|
DevicePool.emitter.on(DEVICE.CONNECT, onDeviceConnectHandler);
|
|
117
163
|
|
|
118
164
|
if (!method.useDevice) {
|
|
165
|
+
updateMethodRequestContext(method, { status: 'running' });
|
|
119
166
|
try {
|
|
120
167
|
const response = await method.run();
|
|
168
|
+
completeMethodRequestContext(method);
|
|
121
169
|
return createResponseMessage(method.responseID, true, response);
|
|
122
170
|
} catch (error) {
|
|
171
|
+
completeMethodRequestContext(method, error);
|
|
123
172
|
return createResponseMessage(method.responseID, false, { error });
|
|
124
173
|
}
|
|
125
174
|
}
|
|
@@ -191,6 +240,8 @@ const onCallDevice = async (
|
|
|
191
240
|
|
|
192
241
|
const { requestQueue, getPrePendingCallPromise, setPrePendingCallPromise } = context;
|
|
193
242
|
|
|
243
|
+
updateMethodRequestContext(method, { status: 'running' });
|
|
244
|
+
|
|
194
245
|
const connectStateChange = preConnectCache.passphraseState !== method.payload.passphraseState;
|
|
195
246
|
|
|
196
247
|
preConnectCache = {
|
|
@@ -225,6 +276,8 @@ const onCallDevice = async (
|
|
|
225
276
|
} catch (e) {
|
|
226
277
|
console.log('ensureConnected error: ', e);
|
|
227
278
|
|
|
279
|
+
completeMethodRequestContext(method, e);
|
|
280
|
+
|
|
228
281
|
if (e.name === 'AbortError' || e.message === 'Request aborted') {
|
|
229
282
|
requestQueue.releaseTask(method.responseID);
|
|
230
283
|
return createResponseMessage(method.responseID, false, {
|
|
@@ -239,6 +292,19 @@ const onCallDevice = async (
|
|
|
239
292
|
method.setDevice?.(device);
|
|
240
293
|
method.context = context;
|
|
241
294
|
|
|
295
|
+
updateMethodRequestContext(method, {
|
|
296
|
+
deviceInstanceId: device.instanceId,
|
|
297
|
+
commandsInstanceId: device.commands?.instanceId,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
const activeRequests = getActiveRequestsByDeviceInstance(device.instanceId);
|
|
301
|
+
if (activeRequests.length > 0) {
|
|
302
|
+
Log.warn(
|
|
303
|
+
`[${method.instanceId}] Device ${device.instanceId} has ${activeRequests.length} active requests:`,
|
|
304
|
+
activeRequests.map(formatRequestContext)
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
242
308
|
device.on(DEVICE.PIN, onDevicePinHandler);
|
|
243
309
|
device.on(DEVICE.BUTTON, onDeviceButtonHandler);
|
|
244
310
|
device.on(
|
|
@@ -452,10 +518,12 @@ const onCallDevice = async (
|
|
|
452
518
|
Log.debug('Call API - Inner Method Run: ');
|
|
453
519
|
messageResponse = createResponseMessage(method.responseID, true, response);
|
|
454
520
|
requestQueue.resolveRequest(method.responseID, messageResponse);
|
|
521
|
+
completeMethodRequestContext(method);
|
|
455
522
|
} catch (error) {
|
|
456
|
-
Log.debug(
|
|
523
|
+
Log.debug(`Call API - Inner Method Run Error`, error);
|
|
457
524
|
messageResponse = createResponseMessage(method.responseID, false, { error });
|
|
458
525
|
requestQueue.resolveRequest(method.responseID, messageResponse);
|
|
526
|
+
completeMethodRequestContext(method, error);
|
|
459
527
|
}
|
|
460
528
|
};
|
|
461
529
|
Log.debug('Call API - Device Run: ', device.mainId);
|
|
@@ -471,6 +539,7 @@ const onCallDevice = async (
|
|
|
471
539
|
return await task.callPromise.promise;
|
|
472
540
|
} catch (e) {
|
|
473
541
|
Log.debug('Device Run Error: ', e);
|
|
542
|
+
completeMethodRequestContext(method, e);
|
|
474
543
|
return createResponseMessage(method.responseID, false, { error: e });
|
|
475
544
|
}
|
|
476
545
|
} catch (error) {
|
|
@@ -480,6 +549,7 @@ const onCallDevice = async (
|
|
|
480
549
|
ERRORS.TypedError(HardwareErrorCode.CallMethodError, error.message)
|
|
481
550
|
);
|
|
482
551
|
Log.debug('Call API - Run Error: ', error);
|
|
552
|
+
completeMethodRequestContext(method, error);
|
|
483
553
|
} finally {
|
|
484
554
|
const response = messageResponse;
|
|
485
555
|
|
|
@@ -507,7 +577,21 @@ const onCallDevice = async (
|
|
|
507
577
|
|
|
508
578
|
cleanup();
|
|
509
579
|
|
|
510
|
-
|
|
580
|
+
if (device) {
|
|
581
|
+
const stillActive = getActiveRequestsByDeviceInstance(device.instanceId);
|
|
582
|
+
if (stillActive.length > 1) {
|
|
583
|
+
Log.warn(
|
|
584
|
+
`[${method.instanceId}] Removing listeners while ${stillActive.length} requests are active!`,
|
|
585
|
+
{
|
|
586
|
+
deviceInstanceId: device.instanceId,
|
|
587
|
+
activeRequests: stillActive.map(formatRequestContext),
|
|
588
|
+
pinListeners: device.listenerCount(DEVICE.PIN),
|
|
589
|
+
}
|
|
590
|
+
);
|
|
591
|
+
} else {
|
|
592
|
+
removeDeviceListener(device);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
511
595
|
}
|
|
512
596
|
};
|
|
513
597
|
|
|
@@ -587,7 +671,10 @@ function initDeviceForBle(method: BaseMethod) {
|
|
|
587
671
|
if (deviceCacheMap.has(method.connectId)) {
|
|
588
672
|
device = deviceCacheMap.get(method.connectId) as Device;
|
|
589
673
|
} else {
|
|
590
|
-
device = Device.fromDescriptor(
|
|
674
|
+
device = Device.fromDescriptor(
|
|
675
|
+
{ id: method.connectId } as OneKeyDeviceInfo,
|
|
676
|
+
method.sdkInstanceId
|
|
677
|
+
);
|
|
591
678
|
deviceCacheMap.set(method.connectId, device);
|
|
592
679
|
}
|
|
593
680
|
device.deviceConnector = _connector;
|
|
@@ -642,7 +729,7 @@ const ensureConnected = async (
|
|
|
642
729
|
if (timer) {
|
|
643
730
|
clearTimeout(timer);
|
|
644
731
|
}
|
|
645
|
-
reject(ERRORS.TypedError(HardwareErrorCode.
|
|
732
|
+
reject(ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled));
|
|
646
733
|
return true;
|
|
647
734
|
}
|
|
648
735
|
return false;
|
|
@@ -806,7 +893,7 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
806
893
|
}
|
|
807
894
|
requestQueue.rejectRequest(
|
|
808
895
|
requestId,
|
|
809
|
-
ERRORS.TypedError(HardwareErrorCode.
|
|
896
|
+
ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled)
|
|
810
897
|
);
|
|
811
898
|
}
|
|
812
899
|
}
|
|
@@ -831,7 +918,7 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
831
918
|
|
|
832
919
|
requestQueue.rejectRequest(
|
|
833
920
|
requestId,
|
|
834
|
-
ERRORS.TypedError(HardwareErrorCode.
|
|
921
|
+
ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled)
|
|
835
922
|
);
|
|
836
923
|
}
|
|
837
924
|
}
|
|
@@ -844,7 +931,10 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
844
931
|
});
|
|
845
932
|
|
|
846
933
|
requestQueue.getRequestTasksId().forEach(requestId => {
|
|
847
|
-
requestQueue.rejectRequest(
|
|
934
|
+
requestQueue.rejectRequest(
|
|
935
|
+
requestId,
|
|
936
|
+
ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled)
|
|
937
|
+
);
|
|
848
938
|
});
|
|
849
939
|
}
|
|
850
940
|
}
|
|
@@ -1005,6 +1095,9 @@ const onSelectDeviceInBootloaderForWebDeviceHandler = async (
|
|
|
1005
1095
|
* @memberof Core
|
|
1006
1096
|
*/
|
|
1007
1097
|
const postMessage = (message: CoreMessage) => {
|
|
1098
|
+
if (!_core) {
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1008
1101
|
_core.emit(CORE_EVENT, message);
|
|
1009
1102
|
};
|
|
1010
1103
|
|
|
@@ -1023,6 +1116,10 @@ const removeUiPromise = (promise: Deferred<any>) => {
|
|
|
1023
1116
|
};
|
|
1024
1117
|
|
|
1025
1118
|
export default class Core extends EventEmitter {
|
|
1119
|
+
private tracingContext: SdkTracingContext;
|
|
1120
|
+
|
|
1121
|
+
public readonly sdkInstanceId: string;
|
|
1122
|
+
|
|
1026
1123
|
private requestQueue = new RequestQueue();
|
|
1027
1124
|
|
|
1028
1125
|
// background task
|
|
@@ -1030,8 +1127,17 @@ export default class Core extends EventEmitter {
|
|
|
1030
1127
|
|
|
1031
1128
|
private methodSynchronize = getSynchronize();
|
|
1032
1129
|
|
|
1130
|
+
constructor() {
|
|
1131
|
+
super();
|
|
1132
|
+
this.tracingContext = createSdkTracingContext();
|
|
1133
|
+
this.sdkInstanceId = this.tracingContext.sdkInstanceId;
|
|
1134
|
+
Log.debug(`[Core] Created SDK instance: ${this.sdkInstanceId}`);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1033
1137
|
private getCoreContext() {
|
|
1034
1138
|
return {
|
|
1139
|
+
sdkInstanceId: this.sdkInstanceId,
|
|
1140
|
+
tracingContext: this.tracingContext,
|
|
1035
1141
|
requestQueue: this.requestQueue,
|
|
1036
1142
|
methodSynchronize: this.methodSynchronize,
|
|
1037
1143
|
getPrePendingCallPromise: () => this.prePendingCallPromise,
|
|
@@ -1109,6 +1215,8 @@ export default class Core extends EventEmitter {
|
|
|
1109
1215
|
dispose() {
|
|
1110
1216
|
_deviceList = undefined;
|
|
1111
1217
|
_connector = undefined;
|
|
1218
|
+
Log.debug(`[Core] Disposing SDK instance: ${this.sdkInstanceId}`);
|
|
1219
|
+
cleanupSdkInstance(this.sdkInstanceId);
|
|
1112
1220
|
}
|
|
1113
1221
|
}
|
|
1114
1222
|
|
|
@@ -1997,6 +1997,15 @@
|
|
|
1997
1997
|
}
|
|
1998
1998
|
}
|
|
1999
1999
|
},
|
|
2000
|
+
"UpgradeFileHeader": {
|
|
2001
|
+
"fields": {
|
|
2002
|
+
"data": {
|
|
2003
|
+
"rule": "required",
|
|
2004
|
+
"type": "bytes",
|
|
2005
|
+
"id": 1
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
},
|
|
2000
2009
|
"CardanoDerivationType": {
|
|
2001
2010
|
"values": {
|
|
2002
2011
|
"LEDGER": 0,
|
|
@@ -12397,7 +12406,8 @@
|
|
|
12397
12406
|
"MessageType_GetPassphraseState": 10028,
|
|
12398
12407
|
"MessageType_PassphraseState": 10029,
|
|
12399
12408
|
"MessageType_UnLockDevice": 10030,
|
|
12400
|
-
"MessageType_UnLockDeviceResponse": 10031
|
|
12409
|
+
"MessageType_UnLockDeviceResponse": 10031,
|
|
12410
|
+
"MessageType_UpgradeFileHeader": 10050
|
|
12401
12411
|
}
|
|
12402
12412
|
},
|
|
12403
12413
|
"google": {
|
package/src/device/Device.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
fixFeaturesFirmwareVersion,
|
|
25
25
|
getPassphraseStateWithRefreshDeviceInfo,
|
|
26
26
|
} from '../utils/deviceFeaturesUtils';
|
|
27
|
+
import { generateInstanceId } from '../utils/tracing';
|
|
27
28
|
|
|
28
29
|
import type DeviceConnector from './DeviceConnector';
|
|
29
30
|
// eslint-disable-next-line import/no-cycle
|
|
@@ -99,6 +100,15 @@ export class Device extends EventEmitter {
|
|
|
99
100
|
*/
|
|
100
101
|
originalDescriptor: DeviceDescriptor;
|
|
101
102
|
|
|
103
|
+
sdkInstanceId?: string;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* 设备实例唯一标识
|
|
107
|
+
*/
|
|
108
|
+
instanceId: string;
|
|
109
|
+
|
|
110
|
+
createdAt: number;
|
|
111
|
+
|
|
102
112
|
/**
|
|
103
113
|
* 设备主 ID
|
|
104
114
|
* 蓝牙连接时是设备的 UUID
|
|
@@ -158,14 +168,22 @@ export class Device extends EventEmitter {
|
|
|
158
168
|
|
|
159
169
|
pendingCallbackPromise?: Deferred<void>;
|
|
160
170
|
|
|
161
|
-
constructor(descriptor: DeviceDescriptor) {
|
|
171
|
+
constructor(descriptor: DeviceDescriptor, sdkInstanceId?: string) {
|
|
162
172
|
super();
|
|
163
173
|
this.originalDescriptor = descriptor;
|
|
174
|
+
this.sdkInstanceId = sdkInstanceId;
|
|
175
|
+
this.instanceId = generateInstanceId('Device', this.sdkInstanceId);
|
|
176
|
+
this.createdAt = Date.now();
|
|
177
|
+
Log.debug(
|
|
178
|
+
`[Device] Created: ${this.instanceId}${
|
|
179
|
+
this.sdkInstanceId ? ` for SDK: ${this.sdkInstanceId}` : ''
|
|
180
|
+
}`
|
|
181
|
+
);
|
|
164
182
|
}
|
|
165
183
|
|
|
166
|
-
static fromDescriptor(originalDescriptor: DeviceDescriptor) {
|
|
184
|
+
static fromDescriptor(originalDescriptor: DeviceDescriptor, sdkInstanceId?: string) {
|
|
167
185
|
const descriptor = { ...originalDescriptor };
|
|
168
|
-
return new Device(descriptor);
|
|
186
|
+
return new Device(descriptor, sdkInstanceId);
|
|
169
187
|
}
|
|
170
188
|
|
|
171
189
|
// simplified object to pass via postMessage
|
|
@@ -183,6 +201,9 @@ export class Device extends EventEmitter {
|
|
|
183
201
|
connectId: DataManager.isBleConnect(env) ? this.mainId || null : getDeviceUUID(this.features),
|
|
184
202
|
/** Hardware ID, will not change at any time */
|
|
185
203
|
uuid: getDeviceUUID(this.features),
|
|
204
|
+
sdkInstanceId: this.sdkInstanceId,
|
|
205
|
+
instanceId: this.instanceId,
|
|
206
|
+
createdAt: this.createdAt,
|
|
186
207
|
deviceType,
|
|
187
208
|
/** ID for current seeds, will clear after replace a new seed at device */
|
|
188
209
|
deviceId: this.features.device_id || null,
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import type { Transport, Messages, FailureType } from '@onekeyfe/hd-transport';
|
|
2
1
|
import { ERRORS, HardwareError, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
3
|
import TransportManager from '../data-manager/TransportManager';
|
|
4
4
|
import DataManager from '../data-manager/DataManager';
|
|
5
|
-
import {
|
|
6
|
-
import type { Device } from './Device';
|
|
5
|
+
import { LoggerNames, getDeviceType, getLogger, patchFeatures } from '../utils';
|
|
7
6
|
import { DEVICE, type PassphraseRequestPayload } from '../events';
|
|
8
7
|
import { DeviceModelToTypes } from '../types';
|
|
8
|
+
import {
|
|
9
|
+
formatRequestContext,
|
|
10
|
+
generateInstanceId,
|
|
11
|
+
getActiveRequestsByDeviceInstance,
|
|
12
|
+
} from '../utils/tracing';
|
|
13
|
+
|
|
14
|
+
import type { Device } from './Device';
|
|
15
|
+
import type { FailureType, Messages, Transport } from '@onekeyfe/hd-transport';
|
|
9
16
|
|
|
10
17
|
export type PassphrasePromptResponse = {
|
|
11
18
|
passphrase?: string;
|
|
@@ -114,12 +121,17 @@ export const cancelDeviceWithInitialize = (device: Device) => {
|
|
|
114
121
|
};
|
|
115
122
|
|
|
116
123
|
const Log = getLogger(LoggerNames.DeviceCommands);
|
|
124
|
+
const LogCore = getLogger(LoggerNames.Core);
|
|
117
125
|
|
|
118
126
|
/**
|
|
119
127
|
* The life cycle begins with the acquisition of the device and ends with the disposal device commands
|
|
120
128
|
* acquire device -> create DeviceCommands -> release device -> dispose DeviceCommands
|
|
121
129
|
*/
|
|
122
130
|
export class DeviceCommands {
|
|
131
|
+
instanceId: string;
|
|
132
|
+
|
|
133
|
+
currentResponseID?: number;
|
|
134
|
+
|
|
123
135
|
device: Device;
|
|
124
136
|
|
|
125
137
|
transport: Transport;
|
|
@@ -135,6 +147,9 @@ export class DeviceCommands {
|
|
|
135
147
|
this.mainId = mainId;
|
|
136
148
|
this.transport = TransportManager.getTransport();
|
|
137
149
|
this.disposed = false;
|
|
150
|
+
this.instanceId = generateInstanceId('DeviceCommands', device.sdkInstanceId);
|
|
151
|
+
|
|
152
|
+
Log.debug(`[DeviceCommands] Created: ${this.instanceId}, device: ${this.device.instanceId}`);
|
|
138
153
|
}
|
|
139
154
|
|
|
140
155
|
async dispose(_cancelRequest: boolean) {
|
|
@@ -217,10 +232,14 @@ export class DeviceCommands {
|
|
|
217
232
|
const promise = this.transport.call(this.mainId, type, msg) as any;
|
|
218
233
|
this.callPromise = promise;
|
|
219
234
|
const res = await promise;
|
|
220
|
-
|
|
235
|
+
if (res.type === 'Failure') {
|
|
236
|
+
LogCore.debug('[DeviceCommands] [call] Received', res.type, res.message);
|
|
237
|
+
} else {
|
|
238
|
+
LogCore.debug('[DeviceCommands] [call] Received', res.type);
|
|
239
|
+
}
|
|
221
240
|
return res;
|
|
222
241
|
} catch (error) {
|
|
223
|
-
|
|
242
|
+
LogCore.debug('[DeviceCommands] [call] Received error', error);
|
|
224
243
|
if (error.errorCode === HardwareErrorCode.BleDeviceBondError) {
|
|
225
244
|
return {
|
|
226
245
|
type: 'BleDeviceBondError',
|
|
@@ -400,14 +419,16 @@ export class DeviceCommands {
|
|
|
400
419
|
message?.includes('verify failed')
|
|
401
420
|
) {
|
|
402
421
|
error = ERRORS.TypedError(HardwareErrorCode.FirmwareVerificationFailed, message);
|
|
422
|
+
} else if (message?.includes('Firmware downgrade not allowed')) {
|
|
423
|
+
// Check firmware check failed
|
|
424
|
+
error = ERRORS.TypedError(HardwareErrorCode.FirmwareDowngradeNotAllowed, message);
|
|
403
425
|
}
|
|
404
426
|
}
|
|
405
427
|
|
|
406
428
|
if (code === 'Failure_UnexpectedMessage') {
|
|
407
429
|
if (callType === 'PassphraseAck') {
|
|
408
430
|
error = ERRORS.TypedError(HardwareErrorCode.UnexpectPassphrase);
|
|
409
|
-
}
|
|
410
|
-
if (message === 'Not in Signing mode') {
|
|
431
|
+
} else if (message === 'Not in Signing mode') {
|
|
411
432
|
error = ERRORS.TypedError(HardwareErrorCode.NotInSigningMode);
|
|
412
433
|
}
|
|
413
434
|
}
|
|
@@ -500,7 +521,7 @@ export class DeviceCommands {
|
|
|
500
521
|
cancelDeviceInPrompt(this.device, false)
|
|
501
522
|
.then(onCancel => {
|
|
502
523
|
const error = ERRORS.TypedError(
|
|
503
|
-
HardwareErrorCode.
|
|
524
|
+
HardwareErrorCode.CallQueueActionCancelled,
|
|
504
525
|
`${DEVICE.PIN} canceled`
|
|
505
526
|
);
|
|
506
527
|
// onCancel not void
|
|
@@ -515,7 +536,15 @@ export class DeviceCommands {
|
|
|
515
536
|
reject(error);
|
|
516
537
|
});
|
|
517
538
|
|
|
518
|
-
|
|
539
|
+
const listenerCount = this.device.listenerCount(DEVICE.PIN);
|
|
540
|
+
|
|
541
|
+
Log.debug(`[${this.instanceId}] _promptPin called`, {
|
|
542
|
+
responseID: this.currentResponseID,
|
|
543
|
+
deviceInstanceId: this.device.instanceId,
|
|
544
|
+
listenerCount,
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
if (listenerCount > 0) {
|
|
519
548
|
this.device.setCancelableAction(cancelAndReject);
|
|
520
549
|
this.device.emit(DEVICE.PIN, this.device, type, (err, pin) => {
|
|
521
550
|
this.device.clearCancelableAction();
|
|
@@ -526,11 +555,22 @@ export class DeviceCommands {
|
|
|
526
555
|
}
|
|
527
556
|
});
|
|
528
557
|
} else {
|
|
529
|
-
|
|
558
|
+
const activeRequests = getActiveRequestsByDeviceInstance(this.device.instanceId);
|
|
559
|
+
const errorInfo = {
|
|
560
|
+
commandsInstanceId: this.instanceId,
|
|
561
|
+
deviceInstanceId: this.device.instanceId,
|
|
562
|
+
currentResponseID: this.currentResponseID,
|
|
563
|
+
listenerCount,
|
|
564
|
+
activeRequests: activeRequests.map(formatRequestContext),
|
|
565
|
+
};
|
|
566
|
+
|
|
567
|
+
LogCore.error('[DeviceCommands] [call] PIN callback not configured, cancelling request', {
|
|
568
|
+
...errorInfo,
|
|
569
|
+
});
|
|
530
570
|
reject(
|
|
531
571
|
ERRORS.TypedError(
|
|
532
572
|
HardwareErrorCode.RuntimeError,
|
|
533
|
-
|
|
573
|
+
`_promptPin: PIN callback not configured: ${JSON.stringify(errorInfo)}`
|
|
534
574
|
)
|
|
535
575
|
);
|
|
536
576
|
}
|
|
@@ -543,7 +583,7 @@ export class DeviceCommands {
|
|
|
543
583
|
cancelDeviceInPrompt(this.device, false)
|
|
544
584
|
.then(onCancel => {
|
|
545
585
|
const error = ERRORS.TypedError(
|
|
546
|
-
HardwareErrorCode.
|
|
586
|
+
HardwareErrorCode.CallQueueActionCancelled,
|
|
547
587
|
`${DEVICE.PASSPHRASE} canceled`
|
|
548
588
|
);
|
|
549
589
|
// onCancel not void
|
|
@@ -574,7 +614,9 @@ export class DeviceCommands {
|
|
|
574
614
|
}
|
|
575
615
|
);
|
|
576
616
|
} else {
|
|
577
|
-
|
|
617
|
+
LogCore.error(
|
|
618
|
+
'[DeviceCommands] [call] Passphrase callback not configured, cancelling request'
|
|
619
|
+
);
|
|
578
620
|
reject(
|
|
579
621
|
ERRORS.TypedError(
|
|
580
622
|
HardwareErrorCode.RuntimeError,
|
package/src/types/device.ts
CHANGED
|
@@ -35,6 +35,11 @@ export type KnownDevice = {
|
|
|
35
35
|
unavailableCapabilities: UnavailableCapabilities;
|
|
36
36
|
bleFirmwareVersion: IVersionArray | null;
|
|
37
37
|
firmwareVersion: IVersionArray | null;
|
|
38
|
+
|
|
39
|
+
// debug sdk
|
|
40
|
+
instanceId?: string;
|
|
41
|
+
sdkInstanceId?: string;
|
|
42
|
+
createdAt?: number;
|
|
38
43
|
};
|
|
39
44
|
|
|
40
45
|
export type SearchDevice = {
|
package/src/utils/index.ts
CHANGED
package/src/utils/logger.ts
CHANGED