@onekeyfe/hd-core 1.2.2-alpha.100 → 1.2.2-alpha.101
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/__tests__/AllNetworkGetAddressBase.tracing.test.ts +20 -4
- package/__tests__/DeviceCommands.test.ts +13 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +0 -2
- package/__tests__/check-firmware-release-protocol-v2.test.ts +0 -2
- package/__tests__/device-lifecycle-events.test.ts +102 -0
- package/__tests__/deviceUploadNft.test.ts +68 -0
- package/__tests__/evmSignTypedData.test.ts +42 -0
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +825 -12
- package/__tests__/logBlockEvent.test.ts +45 -122
- package/__tests__/open-wallet-session.test.ts +781 -69
- package/__tests__/pro2HostAssetPackage.test.ts +165 -0
- package/__tests__/protocol-v2-resources.test.ts +7 -4
- package/__tests__/protocol-v2-unlock-policy.test.ts +35 -1
- package/__tests__/protocol-v2.test.ts +937 -74
- package/__tests__/protocolV2FileWrite.test.ts +40 -0
- package/__tests__/sol-sign-offchain-message.test.ts +70 -0
- package/dist/api/FirmwareUpdateV4.d.ts +5 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +1 -0
- package/dist/api/UploadPortfolio.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 +2 -2
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +2 -2
- package/dist/api/helpers/protocolV2FileWrite.d.ts +1 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
- package/dist/core/RequestQueue.d.ts +2 -0
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/index.d.ts +4 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/uiPromiseRegistry.d.ts +1 -1
- package/dist/device/Device.d.ts +1 -1
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceConnector.d.ts +1 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +3 -0
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +39 -16
- package/dist/index.js +2572 -1554
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +2 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts +3 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +3 -4
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/solSignOffchainMessage.d.ts +2 -0
- package/dist/types/api/solSignOffchainMessage.d.ts.map +1 -1
- package/dist/types/settings.d.ts +2 -2
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +3 -0
- package/dist/utils/deviceFeaturesUtils.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/pro2HostAssetPackage.d.ts +8 -0
- package/dist/utils/pro2HostAssetPackage.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +474 -83
- package/src/api/OpenWalletSession.ts +39 -12
- package/src/api/UploadPortfolio.ts +5 -4
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +5 -2
- package/src/api/evm/EVMSignTypedData.ts +1 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +9 -3
- package/src/api/helpers/protocolV2FileWrite.ts +11 -5
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +7 -1
- package/src/api/protocol-v2/DeviceUploadNft.ts +31 -8
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +33 -8
- package/src/api/protocol-v2/helpers.ts +8 -0
- package/src/api/solana/SolSignOffchainMessage.ts +57 -4
- package/src/core/RequestQueue.ts +16 -1
- package/src/core/index.ts +179 -27
- package/src/data/messages/messages-protocol-v2.json +1562 -1345
- package/src/data/messages/messages.json +8 -5
- package/src/device/Device.ts +3 -1
- package/src/device/DeviceConnector.ts +7 -3
- package/src/events/logBlockEvent.ts +6 -75
- package/src/events/ui-request.ts +3 -0
- package/src/protocols/protocol-v2/resources.ts +9 -1
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +8 -1
- package/src/protocols/protocol-v2/walletSession.ts +223 -56
- package/src/types/api/protocolV2.ts +3 -4
- package/src/types/api/solSignOffchainMessage.ts +3 -0
- package/src/types/settings.ts +4 -2
- package/src/utils/deviceFeaturesUtils.ts +4 -0
- package/src/utils/pro2HostAssetPackage.ts +400 -0
package/src/core/index.ts
CHANGED
|
@@ -2,7 +2,11 @@ import semver from 'semver';
|
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
3
|
import {
|
|
4
4
|
DeviceSessionPinType,
|
|
5
|
+
type LowlevelTransportSharedPlugin,
|
|
6
|
+
type OneKeyDeviceInfo,
|
|
7
|
+
type ProtocolType,
|
|
5
8
|
TRANSPORT_EVENT,
|
|
9
|
+
type TransportDeviceDisconnectEvent,
|
|
6
10
|
isProtocolV2LinkDisabledError,
|
|
7
11
|
} from '@onekeyfe/hd-transport';
|
|
8
12
|
import {
|
|
@@ -18,6 +22,7 @@ import {
|
|
|
18
22
|
createNeedUpgradeFirmwareHardwareError,
|
|
19
23
|
createNewFirmwareForceUpdateHardwareError,
|
|
20
24
|
createNewFirmwareUnReleaseHardwareError,
|
|
25
|
+
isBleStaleBondHardwareError,
|
|
21
26
|
} from '@onekeyfe/hd-shared';
|
|
22
27
|
|
|
23
28
|
import { LoggerNames, enableLog, getLogger, setLoggerPostMessage, wait } from '../utils';
|
|
@@ -74,11 +79,6 @@ import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } fro
|
|
|
74
79
|
import type { DeviceEvents, InitOptions, RunOptions } from '../device/Device';
|
|
75
80
|
import type { SdkTracingContext } from '../utils/tracing';
|
|
76
81
|
import type { Deferred } from '@onekeyfe/hd-shared';
|
|
77
|
-
import type {
|
|
78
|
-
LowlevelTransportSharedPlugin,
|
|
79
|
-
OneKeyDeviceInfo,
|
|
80
|
-
TransportDeviceDisconnectEvent,
|
|
81
|
-
} from '@onekeyfe/hd-transport';
|
|
82
82
|
import type { BaseMethod } from '../api/BaseMethod';
|
|
83
83
|
|
|
84
84
|
const Log = getLogger(LoggerNames.Core);
|
|
@@ -92,7 +92,7 @@ const preWarmDoneAt = new Map<string, number>();
|
|
|
92
92
|
|
|
93
93
|
export type CoreContext = ReturnType<Core['getCoreContext']>;
|
|
94
94
|
|
|
95
|
-
function
|
|
95
|
+
function resolveDeriveCardano(method: BaseMethod): boolean | undefined {
|
|
96
96
|
if (
|
|
97
97
|
method.name.startsWith('allNetworkGetAddress') &&
|
|
98
98
|
method.payload &&
|
|
@@ -102,15 +102,22 @@ function hasDeriveCardano(method: BaseMethod): boolean {
|
|
|
102
102
|
) {
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
if (method.name.startsWith('cardano')) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
// V1 Initialize only sends derive_cardano on an explicit true.
|
|
109
|
+
// V2 AskPassphrase maps true to [Standard, Cardano] and anything else to [Standard].
|
|
110
|
+
if (method.payload?.deriveCardano === true) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return undefined;
|
|
107
114
|
}
|
|
108
115
|
|
|
109
116
|
const parseInitOptions = (method?: BaseMethod): InitOptions => ({
|
|
110
117
|
initSession: method?.payload.initSession,
|
|
111
118
|
passphraseState: method?.payload.useEmptyPassphrase ? undefined : method?.payload.passphraseState,
|
|
112
119
|
deviceId: method?.payload.deviceId,
|
|
113
|
-
deriveCardano: method
|
|
120
|
+
deriveCardano: method ? resolveDeriveCardano(method) : undefined,
|
|
114
121
|
connectProtocol: method?.payload.connectProtocol,
|
|
115
122
|
forceProtocolDetection: method?.payload.forceProtocolDetection,
|
|
116
123
|
protocolV2DeviceInfoTimeoutMs: method?.payload.protocolV2DeviceInfoTimeoutMs,
|
|
@@ -415,6 +422,13 @@ const onCallDevice = async (
|
|
|
415
422
|
if (method.payload?.onlyConnectBleDevice) {
|
|
416
423
|
preWarmCallbackTask?.resolve();
|
|
417
424
|
Log.debug('Call API - only connect ble device: ', device?.mainId);
|
|
425
|
+
// This early return bypasses the normal-path bookkeeping at the end of the
|
|
426
|
+
// call. Without it the task leaks and haunts every later queue snapshot
|
|
427
|
+
// and cancel sweep (field log: a completed task lingered for 6 minutes),
|
|
428
|
+
// and the request stays in the active maps, so repeated preconnects pile
|
|
429
|
+
// up phantom work in diagnostics.
|
|
430
|
+
completeMethodRequestContext(method);
|
|
431
|
+
requestQueue.releaseTask(method.responseID);
|
|
418
432
|
return createResponseMessage(method.responseID, true, null);
|
|
419
433
|
}
|
|
420
434
|
|
|
@@ -644,7 +658,8 @@ const onCallDevice = async (
|
|
|
644
658
|
method.payload?.passphraseState,
|
|
645
659
|
method.payload?.useEmptyPassphrase,
|
|
646
660
|
method.payload?.skipPassphraseCheck,
|
|
647
|
-
|
|
661
|
+
resolveDeriveCardano(method),
|
|
662
|
+
method.protocolV2UnlockContext?.preflightMainPinSelected
|
|
648
663
|
);
|
|
649
664
|
|
|
650
665
|
// Double check, handles the special case of Touch/Pro
|
|
@@ -931,7 +946,16 @@ export function isRetryableBleConnectionError(method: BaseMethod, error: unknown
|
|
|
931
946
|
if (method.device?.wasInterruptedByUser()) {
|
|
932
947
|
return false;
|
|
933
948
|
}
|
|
934
|
-
const typedError = error as {
|
|
949
|
+
const typedError = error as {
|
|
950
|
+
errorCode?: unknown;
|
|
951
|
+
params?: { acquireDeadlineExceeded?: unknown };
|
|
952
|
+
};
|
|
953
|
+
if (
|
|
954
|
+
typedError?.errorCode === HardwareErrorCode.BleTimeoutError &&
|
|
955
|
+
typedError.params?.acquireDeadlineExceeded === true
|
|
956
|
+
) {
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
935
959
|
return (
|
|
936
960
|
typedError?.errorCode === HardwareErrorCode.BleTimeoutError ||
|
|
937
961
|
typedError?.errorCode === HardwareErrorCode.BleConnectedError ||
|
|
@@ -950,11 +974,75 @@ export function isMissingDetectedProtocolV2Error(method: BaseMethod, error: unkn
|
|
|
950
974
|
);
|
|
951
975
|
}
|
|
952
976
|
|
|
977
|
+
export function isTerminalBleStaleBondError(error: unknown) {
|
|
978
|
+
return isBleStaleBondHardwareError(error);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
export function isDeviceIdentityMismatchError(error: unknown) {
|
|
982
|
+
return (
|
|
983
|
+
(error as { errorCode?: unknown })?.errorCode === HardwareErrorCode.DeviceCheckDeviceIdError
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
|
|
953
987
|
/**
|
|
954
988
|
* If the Bluetooth connection times out, retry up to 6 times
|
|
955
989
|
* @param retryCount - Current retry count (default 0)
|
|
956
990
|
*/
|
|
957
|
-
|
|
991
|
+
// device.acquire awaits a transport reply with no deadline of its own; a
|
|
992
|
+
// transport that never settles (field case: Electron main lost an IPC reply,
|
|
993
|
+
// "reply was never sent" after 5 minutes) hangs the call forever and cancel()
|
|
994
|
+
// only takes effect at poll checkpoints. Race acquire against a deadline and
|
|
995
|
+
// the caller's abort signal so the hang is bounded and cancel is immediate.
|
|
996
|
+
const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
|
|
997
|
+
|
|
998
|
+
function raceBleAcquire<T>(acquirePromise: Promise<T>, abortSignal?: AbortSignal): Promise<T> {
|
|
999
|
+
return new Promise<T>((resolve, reject) => {
|
|
1000
|
+
let settled = false;
|
|
1001
|
+
const settle = (fn: () => void) => {
|
|
1002
|
+
if (settled) return;
|
|
1003
|
+
settled = true;
|
|
1004
|
+
clearTimeout(deadline);
|
|
1005
|
+
abortSignal?.removeEventListener('abort', onAbort);
|
|
1006
|
+
fn();
|
|
1007
|
+
};
|
|
1008
|
+
const onAbort = () =>
|
|
1009
|
+
settle(() => reject(ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled)));
|
|
1010
|
+
const deadline = setTimeout(
|
|
1011
|
+
() =>
|
|
1012
|
+
settle(() =>
|
|
1013
|
+
reject(
|
|
1014
|
+
ERRORS.TypedError(
|
|
1015
|
+
HardwareErrorCode.BleTimeoutError,
|
|
1016
|
+
`BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`,
|
|
1017
|
+
{ acquireDeadlineExceeded: true }
|
|
1018
|
+
)
|
|
1019
|
+
)
|
|
1020
|
+
),
|
|
1021
|
+
BLE_ACQUIRE_DEADLINE_MS
|
|
1022
|
+
);
|
|
1023
|
+
// Attach before any early return so a late settlement of acquirePromise
|
|
1024
|
+
// is always consumed — an abort or deadline must never leave the acquire
|
|
1025
|
+
// rejection unhandled.
|
|
1026
|
+
acquirePromise.then(
|
|
1027
|
+
value => settle(() => resolve(value)),
|
|
1028
|
+
error => settle(() => reject(error))
|
|
1029
|
+
);
|
|
1030
|
+
if (abortSignal) {
|
|
1031
|
+
if (abortSignal.aborted) {
|
|
1032
|
+
onAbort();
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
abortSignal.addEventListener('abort', onAbort);
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
async function connectDeviceForBle(
|
|
1041
|
+
method: BaseMethod,
|
|
1042
|
+
device: Device,
|
|
1043
|
+
abortSignal?: AbortSignal,
|
|
1044
|
+
retryCount = 0
|
|
1045
|
+
) {
|
|
958
1046
|
try {
|
|
959
1047
|
if (device.wasInterruptedByUser()) {
|
|
960
1048
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
|
|
@@ -968,9 +1056,44 @@ async function connectDeviceForBle(method: BaseMethod, device: Device, retryCoun
|
|
|
968
1056
|
!device.commands ||
|
|
969
1057
|
device.commands.disposed;
|
|
970
1058
|
if (shouldAcquire) {
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1059
|
+
const connectProtocol = resolveBleConnectProtocol(method);
|
|
1060
|
+
// The deadline/abort guards are scoped to the desktop electron
|
|
1061
|
+
// transport: its IPC acquire is the only path with a proven
|
|
1062
|
+
// never-settling failure mode, while react-native/lowlevel acquire may
|
|
1063
|
+
// legitimately block on a user-driven system bonding prompt for longer
|
|
1064
|
+
// than any sane deadline. Other envs keep the plain acquire unchanged.
|
|
1065
|
+
const useAcquireGuards = DataManager.getSettings('env') === 'desktop-web-ble';
|
|
1066
|
+
// A cancel landing during the retry backoff must not start a new acquire.
|
|
1067
|
+
if (useAcquireGuards && abortSignal?.aborted) {
|
|
1068
|
+
throw ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled);
|
|
1069
|
+
}
|
|
1070
|
+
if (!useAcquireGuards) {
|
|
1071
|
+
await device.acquire(connectProtocol, {
|
|
1072
|
+
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
1073
|
+
});
|
|
1074
|
+
} else {
|
|
1075
|
+
try {
|
|
1076
|
+
await raceBleAcquire(
|
|
1077
|
+
device.acquire(connectProtocol, {
|
|
1078
|
+
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
1079
|
+
}),
|
|
1080
|
+
abortSignal
|
|
1081
|
+
);
|
|
1082
|
+
} catch (err) {
|
|
1083
|
+
// A deadline hit means the transport is wedged mid-acquire; drop the
|
|
1084
|
+
// link before the retry so it cold-connects instead of stacking a
|
|
1085
|
+
// second connect onto the half-open one.
|
|
1086
|
+
if (
|
|
1087
|
+
err.errorCode === HardwareErrorCode.BleTimeoutError &&
|
|
1088
|
+
device.mainId &&
|
|
1089
|
+
device.deviceConnector
|
|
1090
|
+
) {
|
|
1091
|
+
await device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
|
|
1092
|
+
device.markTransportDisconnected();
|
|
1093
|
+
}
|
|
1094
|
+
throw err;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
974
1097
|
}
|
|
975
1098
|
if (method.payload?.onlyConnectBleDevice) {
|
|
976
1099
|
if (shouldAcquire) {
|
|
@@ -1010,13 +1133,21 @@ async function connectDeviceForBle(method: BaseMethod, device: Device, retryCoun
|
|
|
1010
1133
|
const nextRetry = retryCount + 1;
|
|
1011
1134
|
Log.debug(`Bluetooth connection will retry, retry count: ${nextRetry}`);
|
|
1012
1135
|
await wait(3000);
|
|
1013
|
-
await connectDeviceForBle(method, device, nextRetry);
|
|
1136
|
+
await connectDeviceForBle(method, device, abortSignal, nextRetry);
|
|
1014
1137
|
} else {
|
|
1015
1138
|
throw err;
|
|
1016
1139
|
}
|
|
1017
1140
|
}
|
|
1018
1141
|
}
|
|
1019
1142
|
|
|
1143
|
+
export function resolveBleConnectProtocol(method: BaseMethod): ProtocolType | undefined {
|
|
1144
|
+
if (method.payload.connectProtocol === 'V1' || method.payload.connectProtocol === 'V2') {
|
|
1145
|
+
return method.payload.connectProtocol;
|
|
1146
|
+
}
|
|
1147
|
+
const supportedProtocols = method.getSupportedProtocols();
|
|
1148
|
+
return supportedProtocols.length === 1 && supportedProtocols[0] === 'V2' ? 'V2' : undefined;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1020
1151
|
type IPollFn<T> = (time?: number) => T;
|
|
1021
1152
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
1022
1153
|
const ensureConnected = async (
|
|
@@ -1120,7 +1251,7 @@ const ensureConnected = async (
|
|
|
1120
1251
|
if (tryCount === 1) {
|
|
1121
1252
|
device.beginConnectionAttempt();
|
|
1122
1253
|
}
|
|
1123
|
-
await connectDeviceForBle(method, device);
|
|
1254
|
+
await connectDeviceForBle(method, device, abortSignal);
|
|
1124
1255
|
}
|
|
1125
1256
|
resolve(device);
|
|
1126
1257
|
return;
|
|
@@ -1164,7 +1295,9 @@ const ensureConnected = async (
|
|
|
1164
1295
|
HardwareErrorCode.BridgeNeedsPermission,
|
|
1165
1296
|
HardwareErrorCode.DeviceInterruptedFromUser,
|
|
1166
1297
|
HardwareErrorCode.CallQueueActionCancelled,
|
|
1167
|
-
].includes(error.errorCode)
|
|
1298
|
+
].includes(error.errorCode) ||
|
|
1299
|
+
isTerminalBleStaleBondError(error) ||
|
|
1300
|
+
isDeviceIdentityMismatchError(error)
|
|
1168
1301
|
) {
|
|
1169
1302
|
reject(error);
|
|
1170
1303
|
return;
|
|
@@ -1214,12 +1347,17 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1214
1347
|
// cancel callback tasks
|
|
1215
1348
|
requestQueue.cancelCallbackTasks(connectId);
|
|
1216
1349
|
|
|
1217
|
-
const requestIds = requestQueue.
|
|
1350
|
+
const requestIds = requestQueue.getRequestTasksIdByConnectId(connectId);
|
|
1218
1351
|
Log.debug(
|
|
1219
1352
|
`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(
|
|
1220
1353
|
','
|
|
1221
1354
|
)}`
|
|
1222
1355
|
);
|
|
1356
|
+
// Abort before rejecting: rejectRequest releases the task and would make
|
|
1357
|
+
// its AbortController unreachable to an in-flight method loop.
|
|
1358
|
+
// Match both the requested connectId and a device selected internally by the
|
|
1359
|
+
// method, such as Desktop WebUSB firmwareUpdateV4.
|
|
1360
|
+
requestQueue.abortRequestsByConnectId(connectId);
|
|
1223
1361
|
const canceledDevices: Device[] = [];
|
|
1224
1362
|
const interruptDevice = (device: Device | undefined, deviceConnectId: string) => {
|
|
1225
1363
|
if (!device || canceledDevices.includes(device)) {
|
|
@@ -1235,7 +1373,7 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1235
1373
|
// During ensureConnected the method has a connectId but device is
|
|
1236
1374
|
// assigned only after the poll succeeds. Interrupt the cached BLE
|
|
1237
1375
|
// Device so an in-flight acquire/initialize cannot finish.
|
|
1238
|
-
interruptDevice(task.method?.device,
|
|
1376
|
+
interruptDevice(task.method?.device, connectId);
|
|
1239
1377
|
interruptDevice(deviceCacheMap.get(connectId), connectId);
|
|
1240
1378
|
requestQueue.rejectRequest(
|
|
1241
1379
|
requestId,
|
|
@@ -1244,13 +1382,15 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1244
1382
|
}
|
|
1245
1383
|
}
|
|
1246
1384
|
interruptDevice(deviceCacheMap.get(connectId), connectId);
|
|
1247
|
-
requestQueue.abortRequestsByConnectId(connectId);
|
|
1248
1385
|
pollingManager.stop(connectId);
|
|
1249
1386
|
} catch (e) {
|
|
1250
1387
|
Log.error('Cancel API Error: ', e);
|
|
1251
1388
|
}
|
|
1252
1389
|
} else {
|
|
1253
1390
|
const env = DataManager.getSettings('env');
|
|
1391
|
+
// Abort every method before rejecting its queue task. Non-BLE methods also
|
|
1392
|
+
// use the signal to stop recovery loops after the public promise is rejected.
|
|
1393
|
+
requestQueue.abortAllRequests();
|
|
1254
1394
|
if (DataManager.isBleConnect(env)) {
|
|
1255
1395
|
Log.debug('Cancel Api all _deviceList: ');
|
|
1256
1396
|
const canceledDevices: Device[] = [];
|
|
@@ -1277,7 +1417,6 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1277
1417
|
}
|
|
1278
1418
|
}
|
|
1279
1419
|
deviceCacheMap.forEach(interruptDevice);
|
|
1280
|
-
requestQueue.abortAllRequests();
|
|
1281
1420
|
pollingManager.stopAll();
|
|
1282
1421
|
} else {
|
|
1283
1422
|
_deviceList?.allDevices().forEach(device => {
|
|
@@ -1296,8 +1435,10 @@ export const cancel = (context: CoreContext, connectId?: string) => {
|
|
|
1296
1435
|
}
|
|
1297
1436
|
}
|
|
1298
1437
|
|
|
1299
|
-
cleanup();
|
|
1300
|
-
|
|
1438
|
+
cleanup(connectId);
|
|
1439
|
+
if (!connectId || _uiPromises.length === 0) {
|
|
1440
|
+
closePopup();
|
|
1441
|
+
}
|
|
1301
1442
|
};
|
|
1302
1443
|
|
|
1303
1444
|
const checkPassphraseEnableState = (method: BaseMethod, features?: Features) => {
|
|
@@ -1328,12 +1469,23 @@ const checkPassphraseEnableState = (method: BaseMethod, features?: Features) =>
|
|
|
1328
1469
|
const shouldCheckPassphraseState = (method: BaseMethod, device: Device) => {
|
|
1329
1470
|
if (!method.useDevicePassphraseState) return false;
|
|
1330
1471
|
|
|
1472
|
+
if (device.isProtocolV2() && method.payload?.useEmptyPassphrase === true) {
|
|
1473
|
+
return true;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1331
1476
|
return device.hasUsePassphrase();
|
|
1332
1477
|
};
|
|
1333
1478
|
|
|
1334
|
-
const cleanup = () => {
|
|
1335
|
-
const pendingUiPromises =
|
|
1336
|
-
|
|
1479
|
+
const cleanup = (connectId?: string) => {
|
|
1480
|
+
const pendingUiPromises = connectId
|
|
1481
|
+
? _uiPromises.filter(
|
|
1482
|
+
uiPromise =>
|
|
1483
|
+
uiPromise.data?.mainId === connectId || uiPromise.data?.getConnectId() === connectId
|
|
1484
|
+
)
|
|
1485
|
+
: _uiPromises;
|
|
1486
|
+
_uiPromises = connectId
|
|
1487
|
+
? _uiPromises.filter(uiPromise => !pendingUiPromises.includes(uiPromise))
|
|
1488
|
+
: [];
|
|
1337
1489
|
rejectUiPromises(
|
|
1338
1490
|
pendingUiPromises,
|
|
1339
1491
|
ERRORS.TypedError(HardwareErrorCode.ActionCancelled, 'UI request was cancelled')
|