@onekeyfe/hd-core 1.2.0-alpha.52 → 1.2.0-alpha.53
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 +78 -0
- package/__tests__/DeviceCommands.test.ts +45 -0
- package/__tests__/DeviceEventRegistration.test.ts +6 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +198 -3
- package/__tests__/connectSettings.test.ts +5 -47
- package/__tests__/device-lifecycle-events.test.ts +105 -3
- package/__tests__/deviceUploadNft.test.ts +293 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
- package/__tests__/get-device-state.test.ts +132 -12
- package/__tests__/homescreen.test.ts +41 -1
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +19 -0
- package/__tests__/open-wallet-session.test.ts +446 -33
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/protocol-binding.test.ts +89 -0
- package/__tests__/protocol-v2-resources.test.ts +284 -0
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +201 -35
- package/__tests__/protocol-v2.test.ts +1349 -1005
- package/__tests__/protocolV2UiInteraction.test.ts +63 -0
- package/__tests__/public-pro2-api-boundary.test.ts +1 -0
- package/__tests__/search-devices.test.ts +12 -3
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/__tests__/uiPromiseRegistry.test.ts +86 -0
- package/dist/api/BaseMethod.d.ts +3 -1
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +2 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +0 -11
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +3 -7
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +11 -25
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +2 -2
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +0 -9
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +0 -7
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/updateBootloader.d.ts +0 -2
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +1 -9
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +2 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/core/deviceEventRegistration.d.ts +2 -0
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/uiPromiseRegistry.d.ts +4 -0
- package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
- package/dist/data-manager/DataManager.d.ts +4 -2
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +29 -6
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/events/device.d.ts +4 -0
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-promise.d.ts +4 -2
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +31 -2
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +10 -2
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +214 -231
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2559 -3497
- package/dist/inject.d.ts +6 -1
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/resources.d.ts +30 -0
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +5 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +2 -4
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/types/api/deviceUnlock.d.ts +5 -1
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +2 -4
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +2 -70
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +7 -10
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +3 -0
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +22 -13
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +4 -0
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.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/pro2Nft.d.ts +31 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -0
- package/dist/utils/pro2Wallpaper.d.ts +10 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/dist/utils/uiProgressThrottle.d.ts +3 -0
- package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +8 -10
- package/src/api/CheckAllFirmwareRelease.ts +54 -57
- package/src/api/DetectDeviceConnectProtocol.ts +18 -0
- package/src/api/FirmwareUpdate.ts +7 -15
- package/src/api/FirmwareUpdateV2.ts +126 -316
- package/src/api/FirmwareUpdateV3.ts +63 -265
- package/src/api/FirmwareUpdateV4.ts +566 -965
- package/src/api/GetPassphraseState.ts +7 -1
- package/src/api/OpenWalletSession.ts +54 -17
- package/src/api/SearchDevices.ts +3 -1
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +32 -11
- package/src/api/device/DeviceUnlock.ts +8 -3
- package/src/api/device/DeviceUpdateBootloader.ts +6 -122
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +16 -83
- package/src/api/firmware/updateBootloader.ts +4 -19
- package/src/api/firmware/uploadFirmware.ts +39 -144
- package/src/api/helpers/protocolV2FileWrite.ts +11 -4
- package/src/api/index.ts +2 -0
- package/src/api/protocol-v2/DeviceUploadNft.ts +189 -0
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
- package/src/api/protocol-v2/helpers.ts +1 -0
- package/src/core/deviceEventRegistration.ts +4 -0
- package/src/core/index.ts +167 -83
- package/src/core/uiPromiseRegistry.ts +41 -0
- package/src/data/messages/messages-protocol-v2.json +25 -0
- package/src/data-manager/DataManager.ts +67 -38
- package/src/data-manager/connectSettings.ts +0 -11
- package/src/device/Device.ts +258 -42
- package/src/device/DeviceCommands.ts +7 -1
- package/src/device/DevicePool.ts +7 -2
- package/src/events/device.ts +4 -0
- package/src/events/logBlockEvent.ts +1 -0
- package/src/events/ui-promise.ts +4 -2
- package/src/events/ui-request.ts +36 -2
- package/src/events/ui-response.ts +12 -2
- package/src/index.ts +0 -5
- package/src/inject.ts +60 -24
- package/src/lowLevelInject.ts +7 -8
- package/src/protocols/protocol-v2/features.ts +10 -3
- package/src/protocols/protocol-v2/resources.ts +359 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
- package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +118 -0
- package/src/protocols/protocol-v2/walletSession.ts +180 -30
- package/src/topLevelInject.ts +7 -8
- package/src/types/api/checkAllFirmwareRelease.ts +2 -4
- package/src/types/api/detectDeviceConnectProtocol.ts +7 -0
- package/src/types/api/deviceUnlock.ts +12 -1
- package/src/types/api/deviceUpdateBootloader.ts +0 -6
- package/src/types/api/export.ts +1 -18
- package/src/types/api/firmwareUpdate.ts +3 -76
- package/src/types/api/index.ts +13 -14
- package/src/types/api/protocolV2.ts +13 -0
- package/src/types/device.ts +3 -0
- package/src/types/params.ts +7 -1
- package/src/types/settings.ts +42 -13
- package/src/utils/deviceFeaturesCompat.ts +0 -6
- package/src/utils/deviceFeaturesUtils.ts +8 -0
- package/src/utils/homescreen.ts +32 -6
- package/src/utils/index.ts +6 -1
- package/src/utils/pro2Nft.ts +142 -0
- package/src/utils/pro2Wallpaper.ts +35 -8
- package/src/utils/uiProgressThrottle.ts +63 -0
- package/__tests__/device-initialize-timeout.test.ts +0 -56
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
- package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -294
- package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -213
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
- package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
- package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/dist/api/firmware/progressThrottle.d.ts +0 -3
- package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
- package/src/api/firmware/FirmwareHostBinding.ts +0 -100
- package/src/api/firmware/FirmwarePreparationError.ts +0 -12
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
- package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -415
- package/src/api/firmware/progressThrottle.ts +0 -44
- package/src/protocols/protocol-v2/lockedError.ts +0 -10
- package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
- package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
- package/src/types/api/firmwareUpdatePlan.ts +0 -38
- package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
package/src/core/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import semver from 'semver';
|
|
2
2
|
import EventEmitter from 'events';
|
|
3
|
-
import { TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
|
|
3
|
+
import { DeviceSessionPinType, TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
|
|
4
4
|
import {
|
|
5
5
|
ERRORS,
|
|
6
6
|
ERROR_CODES_REQUIRE_RELEASE,
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
createRequestContext,
|
|
27
27
|
createSdkTracingContext,
|
|
28
28
|
formatRequestContext,
|
|
29
|
+
generateInstanceId,
|
|
29
30
|
getActiveRequestsByDeviceInstance,
|
|
30
31
|
updateRequestContext,
|
|
31
32
|
} from '../utils/tracing';
|
|
@@ -53,13 +54,15 @@ import {
|
|
|
53
54
|
import TransportManager from '../data-manager/TransportManager';
|
|
54
55
|
import DeviceConnector from '../device/DeviceConnector';
|
|
55
56
|
import RequestQueue from './RequestQueue';
|
|
57
|
+
import { findUiPromiseForResponse } from './uiPromiseRegistry';
|
|
56
58
|
import { registerHardwareUiEventListeners } from './deviceEventRegistration';
|
|
57
59
|
import { getSynchronize } from '../utils/getSynchronize';
|
|
58
|
-
import {
|
|
60
|
+
import { runMethodWithUnlockPolicy } from '../protocols/protocol-v2/unlockPolicyRunner';
|
|
59
61
|
import {
|
|
60
62
|
ProtocolV2UiInteractionCoordinator,
|
|
61
63
|
isProtocolV2UiEnabled,
|
|
62
64
|
} from '../protocols/protocol-v2/uiInteraction';
|
|
65
|
+
import { createUiProgressMessageFilter } from '../utils/uiProgressThrottle';
|
|
63
66
|
|
|
64
67
|
import type { ConnectSettings, Features, KnownDevice } from '../types';
|
|
65
68
|
import type { CoreMessage, IFrameCallMessage, UiPromise, UiPromiseResponse } from '../events';
|
|
@@ -103,6 +106,7 @@ const parseInitOptions = (method?: BaseMethod): InitOptions => ({
|
|
|
103
106
|
deviceId: method?.payload.deviceId,
|
|
104
107
|
deriveCardano: method && hasDeriveCardano(method),
|
|
105
108
|
connectProtocol: method?.payload.connectProtocol,
|
|
109
|
+
forceProtocolDetection: method?.payload.forceProtocolDetection,
|
|
106
110
|
protocolV2DeviceInfoTimeoutMs: method?.payload.protocolV2DeviceInfoTimeoutMs,
|
|
107
111
|
});
|
|
108
112
|
|
|
@@ -154,7 +158,12 @@ export const callAPI = async (context: CoreContext, message: CoreMessage) => {
|
|
|
154
158
|
try {
|
|
155
159
|
method = findMethod(message as IFrameCallMessage);
|
|
156
160
|
method.connector = _connector;
|
|
157
|
-
|
|
161
|
+
const shouldPostMessage = createUiProgressMessageFilter();
|
|
162
|
+
method.postMessage = event => {
|
|
163
|
+
if (shouldPostMessage(event)) {
|
|
164
|
+
postMessage(event);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
158
167
|
method.setContext?.(context);
|
|
159
168
|
|
|
160
169
|
method.requestContext = createRequestContext(method.responseID, method.name, {
|
|
@@ -406,6 +415,8 @@ const onCallDevice = async (
|
|
|
406
415
|
|
|
407
416
|
registerHardwareUiEventListeners(device, {
|
|
408
417
|
pin: onDevicePinHandler,
|
|
418
|
+
pinOnDevice: onEnterPinOnDeviceHandler,
|
|
419
|
+
pinOnDeviceComplete: onPinOnDeviceCompleteHandler,
|
|
409
420
|
button: onDeviceButtonHandler,
|
|
410
421
|
passphrase: message.payload.useEmptyPassphrase
|
|
411
422
|
? onEmptyPassphraseHandler
|
|
@@ -421,6 +432,9 @@ const onCallDevice = async (
|
|
|
421
432
|
);
|
|
422
433
|
|
|
423
434
|
const protocolV2UiCoordinator = new ProtocolV2UiInteractionCoordinator(device, postMessage);
|
|
435
|
+
let protocolV2Operation = false;
|
|
436
|
+
let protocolV2CloseEmitted = false;
|
|
437
|
+
device.beginProtocolV2UiInteraction();
|
|
424
438
|
device.on(
|
|
425
439
|
DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE,
|
|
426
440
|
onSelectDeviceForSwitchFirmwareWebDeviceHandler
|
|
@@ -438,6 +452,7 @@ const onCallDevice = async (
|
|
|
438
452
|
// Protocol is established from an active device response during acquire/initialize.
|
|
439
453
|
// Reject unsupported methods before any method-specific device command is sent.
|
|
440
454
|
method.assertProtocolSupported(device.getProtocol(), device.getCurrentFirmwareType());
|
|
455
|
+
protocolV2Operation = device.isProtocolV2();
|
|
441
456
|
|
|
442
457
|
// check firmware version
|
|
443
458
|
const versionRange = device.getCurrentMethodVersionRange(
|
|
@@ -547,89 +562,92 @@ const onCallDevice = async (
|
|
|
547
562
|
);
|
|
548
563
|
}
|
|
549
564
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
565
|
+
try {
|
|
566
|
+
let deviceIdCheckedDuringUnlockPreflight = false;
|
|
567
|
+
const response = await runMethodWithUnlockPolicy<object>(method, device, {
|
|
568
|
+
uiCoordinator: protocolV2UiCoordinator,
|
|
569
|
+
afterStatusBeforeUnlock: () => {
|
|
570
|
+
if (method.deviceId && method.checkDeviceId) {
|
|
571
|
+
if (!device.checkDeviceId(method.deviceId)) {
|
|
572
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
573
|
+
}
|
|
574
|
+
deviceIdCheckedDuringUnlockPreflight = true;
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
prepare: async () => {
|
|
578
|
+
if (method.deviceId && method.checkDeviceId && !deviceIdCheckedDuringUnlockPreflight) {
|
|
579
|
+
const isSameDeviceID = await checkLiveDeviceId(device, method.deviceId);
|
|
580
|
+
if (!isSameDeviceID) {
|
|
581
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
561
584
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
585
|
+
/**
|
|
586
|
+
* check firmware release info
|
|
587
|
+
*/
|
|
588
|
+
method.checkFirmwareRelease();
|
|
566
589
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
590
|
+
/**
|
|
591
|
+
* check additional supported feature
|
|
592
|
+
*/
|
|
593
|
+
method.checkDeviceSupportFeature();
|
|
571
594
|
|
|
572
|
-
|
|
573
|
-
|
|
595
|
+
// reconfigure messages
|
|
596
|
+
if (_deviceList && device.features && !device.isProtocolV2()) {
|
|
597
|
+
await TransportManager.reconfigure(device.features);
|
|
598
|
+
}
|
|
574
599
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
600
|
+
// Check to see if it is safe to use Passphrase
|
|
601
|
+
checkPassphraseEnableState(method, device.features);
|
|
602
|
+
|
|
603
|
+
if (shouldCheckPassphraseState(method, device)) {
|
|
604
|
+
// check version
|
|
605
|
+
const support = device.supportNewPassphrase();
|
|
606
|
+
if (!support.support) {
|
|
607
|
+
throw ERRORS.TypedError(
|
|
608
|
+
HardwareErrorCode.DeviceNotSupportPassphrase,
|
|
609
|
+
`Device not support passphrase, please update to ${support.require}`,
|
|
610
|
+
{
|
|
611
|
+
require: support.require,
|
|
612
|
+
}
|
|
613
|
+
);
|
|
585
614
|
}
|
|
586
|
-
)
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
// Check Device passphrase State
|
|
591
|
-
const passphraseStateSafety = await device.checkPassphraseStateSafety(
|
|
592
|
-
method.payload?.passphraseState,
|
|
593
|
-
method.payload?.useEmptyPassphrase,
|
|
594
|
-
method.payload?.skipPassphraseCheck
|
|
595
|
-
);
|
|
596
615
|
|
|
597
|
-
|
|
598
|
-
|
|
616
|
+
// Check Device passphrase State after the Protocol V2 pre-unlock gate.
|
|
617
|
+
const passphraseStateSafety = await device.checkPassphraseStateSafety(
|
|
618
|
+
method.payload?.passphraseState,
|
|
619
|
+
method.payload?.useEmptyPassphrase,
|
|
620
|
+
method.payload?.skipPassphraseCheck,
|
|
621
|
+
hasDeriveCardano(method)
|
|
622
|
+
);
|
|
599
623
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
return Promise.reject(
|
|
603
|
-
ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError)
|
|
604
|
-
);
|
|
605
|
-
}
|
|
624
|
+
// Double check, handles the special case of Touch/Pro
|
|
625
|
+
checkPassphraseEnableState(method, device.features);
|
|
606
626
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
627
|
+
if (!passphraseStateSafety) {
|
|
628
|
+
DevicePool.clearDeviceCache(method.payload.connectId);
|
|
629
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckPassphraseStateError);
|
|
630
|
+
}
|
|
610
631
|
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
? e
|
|
618
|
-
: ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'open safety check failed.');
|
|
619
|
-
// messageResponse = createResponseMessage(method.responseID, false, { error });
|
|
620
|
-
// requestQueue.resolveRequest(method.responseID, messageResponse);
|
|
621
|
-
// return;
|
|
622
|
-
throw error;
|
|
623
|
-
}
|
|
632
|
+
// Protocol V2 emits the PIN phase completion from DeviceSessionAskPin.
|
|
633
|
+
// Keep the legacy compatibility close for Protocol V1 only.
|
|
634
|
+
if (!device.isProtocolV2()) {
|
|
635
|
+
postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW));
|
|
636
|
+
}
|
|
637
|
+
}
|
|
624
638
|
|
|
625
|
-
|
|
639
|
+
// Automatic check safety_check level for Kovan, Ropsten, Rinkeby, Goerli test networks.
|
|
640
|
+
try {
|
|
641
|
+
await method.checkSafetyLevelOnTestNet();
|
|
642
|
+
} catch (e) {
|
|
643
|
+
throw e instanceof HardwareError
|
|
644
|
+
? e
|
|
645
|
+
: ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'open safety check failed.');
|
|
646
|
+
}
|
|
626
647
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
device,
|
|
631
|
-
protocolV2UiCoordinator
|
|
632
|
-
);
|
|
648
|
+
method.device?.commands?.checkDisposed();
|
|
649
|
+
},
|
|
650
|
+
});
|
|
633
651
|
messageResponse = createResponseMessage(method.responseID, true, response);
|
|
634
652
|
requestQueue.resolveRequest(method.responseID, messageResponse);
|
|
635
653
|
completeMethodRequestContext(method);
|
|
@@ -647,7 +665,12 @@ const onCallDevice = async (
|
|
|
647
665
|
throw error;
|
|
648
666
|
}
|
|
649
667
|
} finally {
|
|
650
|
-
|
|
668
|
+
if (isProtocolV2UiEnabled(method)) {
|
|
669
|
+
protocolV2CloseEmitted = protocolV2UiCoordinator.close({
|
|
670
|
+
ensureOperationClose: protocolV2Operation,
|
|
671
|
+
protocolV2Operation,
|
|
672
|
+
});
|
|
673
|
+
}
|
|
651
674
|
}
|
|
652
675
|
};
|
|
653
676
|
Log.debug('Call API - Device Run: ', device.mainId);
|
|
@@ -702,7 +725,15 @@ const onCallDevice = async (
|
|
|
702
725
|
requestQueue.releaseTask(method.responseID);
|
|
703
726
|
|
|
704
727
|
if (isProtocolV2UiEnabled(method)) {
|
|
705
|
-
|
|
728
|
+
if (!protocolV2CloseEmitted && protocolV2Operation) {
|
|
729
|
+
protocolV2CloseEmitted = protocolV2UiCoordinator.close({
|
|
730
|
+
ensureOperationClose: true,
|
|
731
|
+
protocolV2Operation: true,
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
if (!protocolV2CloseEmitted) {
|
|
735
|
+
closePopup();
|
|
736
|
+
}
|
|
706
737
|
}
|
|
707
738
|
|
|
708
739
|
cleanup();
|
|
@@ -865,10 +896,18 @@ function isRetryableBleProtocolV2ProbeError(method: BaseMethod, error: unknown)
|
|
|
865
896
|
*/
|
|
866
897
|
async function connectDeviceForBle(method: BaseMethod, device: Device, retryCount = 0) {
|
|
867
898
|
try {
|
|
899
|
+
if (method.payload.forceProtocolDetection && device.hasDeviceAcquire()) {
|
|
900
|
+
await device.release();
|
|
901
|
+
}
|
|
868
902
|
const shouldAcquire =
|
|
869
|
-
|
|
903
|
+
method.payload.forceProtocolDetection ||
|
|
904
|
+
!device.hasDeviceAcquire() ||
|
|
905
|
+
!device.commands ||
|
|
906
|
+
device.commands.disposed;
|
|
870
907
|
if (shouldAcquire) {
|
|
871
|
-
await device.acquire(method.payload.connectProtocol
|
|
908
|
+
await device.acquire(method.payload.connectProtocol, {
|
|
909
|
+
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
910
|
+
});
|
|
872
911
|
}
|
|
873
912
|
if (method.payload?.onlyConnectBleDevice) {
|
|
874
913
|
if (shouldAcquire) {
|
|
@@ -1232,6 +1271,7 @@ const onDevicePinHandler = async (...[device, type, callback]: DeviceEvents['pin
|
|
|
1232
1271
|
createUiMessage(UI_REQUEST.REQUEST_PIN, {
|
|
1233
1272
|
device: device.toMessageObject() as unknown as KnownDevice,
|
|
1234
1273
|
type,
|
|
1274
|
+
responseCorrelation: uiPromise.responseCorrelation,
|
|
1235
1275
|
})
|
|
1236
1276
|
);
|
|
1237
1277
|
// wait for pin
|
|
@@ -1279,6 +1319,8 @@ const onDevicePassphraseHandler = async (
|
|
|
1279
1319
|
source: requestPayload.source,
|
|
1280
1320
|
reason: requestPayload.reason,
|
|
1281
1321
|
expectedPassphraseState: requestPayload.expectedPassphraseState,
|
|
1322
|
+
...(requestPayload.interaction ? { interaction: requestPayload.interaction } : {}),
|
|
1323
|
+
responseCorrelation: uiPromise.responseCorrelation,
|
|
1282
1324
|
})
|
|
1283
1325
|
);
|
|
1284
1326
|
// wait for passphrase
|
|
@@ -1308,6 +1350,7 @@ const onEnterPassphraseOnDeviceHandler = (
|
|
|
1308
1350
|
passphraseState: device.passphraseState,
|
|
1309
1351
|
source: requestPayload?.source,
|
|
1310
1352
|
reason: requestPayload?.reason,
|
|
1353
|
+
...(requestPayload?.interaction ? { interaction: requestPayload.interaction } : {}),
|
|
1311
1354
|
})
|
|
1312
1355
|
);
|
|
1313
1356
|
};
|
|
@@ -1321,10 +1364,39 @@ const onEnterAttachPinOnDeviceHandler = (
|
|
|
1321
1364
|
type: 'ButtonRequest_AttachPin',
|
|
1322
1365
|
source: requestPayload?.source,
|
|
1323
1366
|
reason: requestPayload?.reason,
|
|
1367
|
+
...(requestPayload?.interaction ? { interaction: requestPayload.interaction } : {}),
|
|
1368
|
+
})
|
|
1369
|
+
);
|
|
1370
|
+
};
|
|
1371
|
+
|
|
1372
|
+
const onEnterPinOnDeviceHandler = (
|
|
1373
|
+
...[device, pinType, metadata]: [...DeviceEvents['pin_on_device']]
|
|
1374
|
+
) => {
|
|
1375
|
+
postMessage(
|
|
1376
|
+
createUiMessage(UI_REQUEST.REQUEST_PIN, {
|
|
1377
|
+
device: device.toMessageObject() as KnownDevice,
|
|
1378
|
+
type:
|
|
1379
|
+
pinType === DeviceSessionPinType.AttachToPin
|
|
1380
|
+
? 'ButtonRequest_AttachPin'
|
|
1381
|
+
: 'ButtonRequest_PinEntry',
|
|
1382
|
+
source: metadata?.source,
|
|
1383
|
+
reason: metadata?.reason,
|
|
1384
|
+
deviceOnly: metadata?.deviceOnly ?? true,
|
|
1385
|
+
completion: metadata?.completion,
|
|
1386
|
+
method: metadata?.method,
|
|
1387
|
+
page: metadata?.page,
|
|
1388
|
+
operation: metadata?.operation,
|
|
1389
|
+
...(metadata?.interaction ? { interaction: metadata.interaction } : {}),
|
|
1324
1390
|
})
|
|
1325
1391
|
);
|
|
1326
1392
|
};
|
|
1327
1393
|
|
|
1394
|
+
const onPinOnDeviceCompleteHandler = (
|
|
1395
|
+
...[_, metadata]: [...DeviceEvents['pin_on_device_complete']]
|
|
1396
|
+
) => {
|
|
1397
|
+
postMessage(createUiMessage(UI_REQUEST.CLOSE_UI_PIN_WINDOW, metadata));
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1328
1400
|
const onSelectDeviceInBootloaderForWebDeviceHandler = async (
|
|
1329
1401
|
...[device, callback]: [...DeviceEvents['select_device_in_bootloader_for_web_device']]
|
|
1330
1402
|
) => {
|
|
@@ -1372,14 +1444,21 @@ const postMessage = (message: CoreMessage) => {
|
|
|
1372
1444
|
|
|
1373
1445
|
const createUiPromise = <T extends UiPromiseResponse['type']>(promiseEvent: T, device?: Device) => {
|
|
1374
1446
|
const uiPromise: UiPromise<T> = createDeferred(promiseEvent, device);
|
|
1447
|
+
if (
|
|
1448
|
+
device &&
|
|
1449
|
+
(promiseEvent === UI_RESPONSE.RECEIVE_PIN || promiseEvent === UI_RESPONSE.RECEIVE_PASSPHRASE)
|
|
1450
|
+
) {
|
|
1451
|
+
const publicDeviceId = device.toMessageObject()?.deviceId;
|
|
1452
|
+
uiPromise.responseCorrelation = {
|
|
1453
|
+
interactionId: generateInstanceId('UiResponse', device.sdkInstanceId),
|
|
1454
|
+
deviceId: publicDeviceId || device.instanceId,
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1375
1457
|
_uiPromises.push(uiPromise as any);
|
|
1376
1458
|
|
|
1377
1459
|
return uiPromise;
|
|
1378
1460
|
};
|
|
1379
1461
|
|
|
1380
|
-
const findUiPromise = <T extends UiPromiseResponse['type']>(promiseEvent: T) =>
|
|
1381
|
-
_uiPromises.find(p => p.id === promiseEvent);
|
|
1382
|
-
|
|
1383
1462
|
const removeUiPromise = (promise: Deferred<any>) => {
|
|
1384
1463
|
_uiPromises = _uiPromises.filter(p => p !== promise);
|
|
1385
1464
|
};
|
|
@@ -1431,11 +1510,16 @@ export default class Core extends EventEmitter {
|
|
|
1431
1510
|
case UI_RESPONSE.RECEIVE_PASSPHRASE:
|
|
1432
1511
|
case UI_RESPONSE.SELECT_DEVICE_IN_BOOTLOADER_FOR_WEB_DEVICE:
|
|
1433
1512
|
case UI_RESPONSE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE: {
|
|
1434
|
-
const uiPromise =
|
|
1513
|
+
const uiPromise = findUiPromiseForResponse(_uiPromises, message);
|
|
1435
1514
|
if (uiPromise) {
|
|
1436
1515
|
Log.log('receive UI Response: ', message.type);
|
|
1437
1516
|
uiPromise.resolve(message);
|
|
1438
1517
|
removeUiPromise(uiPromise);
|
|
1518
|
+
} else if (
|
|
1519
|
+
message.type === UI_RESPONSE.RECEIVE_PIN ||
|
|
1520
|
+
message.type === UI_RESPONSE.RECEIVE_PASSPHRASE
|
|
1521
|
+
) {
|
|
1522
|
+
Log.warn('Ignored unmatched or ambiguous sensitive UI response:', message.type);
|
|
1439
1523
|
}
|
|
1440
1524
|
break;
|
|
1441
1525
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { UI_RESPONSE } from '../events/ui-response';
|
|
2
|
+
|
|
3
|
+
import type { UiPromise, UiPromiseResponse } from '../events/ui-promise';
|
|
4
|
+
import type { UiResponseEvent } from '../events/ui-response';
|
|
5
|
+
|
|
6
|
+
const isSensitiveUiResponse = (
|
|
7
|
+
response: UiResponseEvent
|
|
8
|
+
): response is Extract<
|
|
9
|
+
UiResponseEvent,
|
|
10
|
+
{ type: typeof UI_RESPONSE.RECEIVE_PIN | typeof UI_RESPONSE.RECEIVE_PASSPHRASE }
|
|
11
|
+
> => response.type === UI_RESPONSE.RECEIVE_PIN || response.type === UI_RESPONSE.RECEIVE_PASSPHRASE;
|
|
12
|
+
|
|
13
|
+
export const findUiPromiseForResponse = (
|
|
14
|
+
uiPromises: UiPromise<UiPromiseResponse['type']>[],
|
|
15
|
+
response: UiResponseEvent
|
|
16
|
+
) => {
|
|
17
|
+
const candidates = uiPromises.filter(promise => promise.id === response.type);
|
|
18
|
+
if (!isSensitiveUiResponse(response)) {
|
|
19
|
+
return candidates[0];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const hasInteractionId = typeof response.interactionId === 'string';
|
|
23
|
+
const hasDeviceId = typeof response.deviceId === 'string';
|
|
24
|
+
if (hasInteractionId !== hasDeviceId) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (hasInteractionId && hasDeviceId) {
|
|
29
|
+
return candidates.find(promise => {
|
|
30
|
+
const correlation = promise.responseCorrelation;
|
|
31
|
+
return (
|
|
32
|
+
correlation?.interactionId === response.interactionId &&
|
|
33
|
+
correlation?.deviceId === response.deviceId
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Legacy clients do not return correlation metadata. Preserve their single-request
|
|
39
|
+
// behavior, but never guess when multiple sensitive requests are pending.
|
|
40
|
+
return candidates.length === 1 ? candidates[0] : undefined;
|
|
41
|
+
};
|
|
@@ -470,6 +470,7 @@
|
|
|
470
470
|
"MessageType_DeviceSessionAskPin": 61202,
|
|
471
471
|
"MessageType_DeviceSessionAskPassphrase": 61203,
|
|
472
472
|
"MessageType_PortfolioUpdate": 61400,
|
|
473
|
+
"MessageType_NftUpdate": 61500,
|
|
473
474
|
"MessageType_OnboardingStatusGet": 61600,
|
|
474
475
|
"MessageType_OnboardingStatus": 61601
|
|
475
476
|
},
|
|
@@ -12200,11 +12201,26 @@
|
|
|
12200
12201
|
"DeviceSessionError_Busy": 5
|
|
12201
12202
|
}
|
|
12202
12203
|
},
|
|
12204
|
+
"DeviceSessionSeedDomain": {
|
|
12205
|
+
"values": {
|
|
12206
|
+
"SeedDomain_Standard": 1,
|
|
12207
|
+
"SeedDomain_Cardano": 2
|
|
12208
|
+
}
|
|
12209
|
+
},
|
|
12203
12210
|
"DeviceSessionGet": {
|
|
12204
12211
|
"fields": {
|
|
12205
12212
|
"session_id": {
|
|
12206
12213
|
"type": "bytes",
|
|
12207
12214
|
"id": 1
|
|
12215
|
+
},
|
|
12216
|
+
"btc_test_address": {
|
|
12217
|
+
"type": "string",
|
|
12218
|
+
"id": 2
|
|
12219
|
+
},
|
|
12220
|
+
"seed_domains": {
|
|
12221
|
+
"rule": "repeated",
|
|
12222
|
+
"type": "DeviceSessionSeedDomain",
|
|
12223
|
+
"id": 3
|
|
12208
12224
|
}
|
|
12209
12225
|
}
|
|
12210
12226
|
},
|
|
@@ -12538,6 +12554,15 @@
|
|
|
12538
12554
|
}
|
|
12539
12555
|
}
|
|
12540
12556
|
},
|
|
12557
|
+
"NftUpdate": {
|
|
12558
|
+
"fields": {
|
|
12559
|
+
"file_name_no_ext": {
|
|
12560
|
+
"rule": "required",
|
|
12561
|
+
"type": "string",
|
|
12562
|
+
"id": 1
|
|
12563
|
+
}
|
|
12564
|
+
}
|
|
12565
|
+
},
|
|
12541
12566
|
"OnboardingStep": {
|
|
12542
12567
|
"values": {
|
|
12543
12568
|
"ONBOARDING_STEP_UNKNOWN": 0,
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
} from '../utils';
|
|
18
18
|
import { DeviceModelToTypes } from '../types';
|
|
19
19
|
import { findLatestRelease, getReleaseChangelog, getReleaseStatus } from '../utils/release';
|
|
20
|
+
import { parseProtocolV2Resources } from '../protocols/protocol-v2/resources';
|
|
20
21
|
|
|
21
22
|
import type {
|
|
22
23
|
AssetsMap,
|
|
@@ -397,20 +398,10 @@ export default class DataManager {
|
|
|
397
398
|
return enrichedData;
|
|
398
399
|
}
|
|
399
400
|
|
|
400
|
-
static async load(settings: ConnectSettings) {
|
|
401
|
+
static async load(settings: ConnectSettings): Promise<boolean> {
|
|
401
402
|
this.settings = settings;
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if (settings.preloadedConfig) {
|
|
405
|
-
this.applyRemoteConfig(settings.preloadedConfig);
|
|
406
|
-
Log.log('[DataConfig] Preloaded firmware config loaded');
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (manifestMode === 'external-only') {
|
|
410
|
-
throw new Error('External firmware config snapshot is required');
|
|
411
|
-
}
|
|
412
|
-
if (manifestMode !== 'sdk-managed') {
|
|
413
|
-
return;
|
|
403
|
+
if (!settings.fetchConfig) {
|
|
404
|
+
return false;
|
|
414
405
|
}
|
|
415
406
|
|
|
416
407
|
const url = settings.preRelease
|
|
@@ -419,48 +410,65 @@ export default class DataManager {
|
|
|
419
410
|
|
|
420
411
|
const urlWithCache = `${url}?noCache=${getTimeStamp()}`;
|
|
421
412
|
let data: RemoteConfigResponse | null = null;
|
|
413
|
+
let fetchMethod: 'configFetcher' | 'axios' | 'none' = 'none';
|
|
414
|
+
|
|
415
|
+
// 1. Try custom configFetcher first (client-side IP direct connection support)
|
|
422
416
|
if (settings.configFetcher) {
|
|
423
|
-
Log.debug('[DataConfig] Trying client
|
|
417
|
+
Log.debug('[DataConfig] Trying configFetcher (client-side fetcher)...');
|
|
424
418
|
try {
|
|
425
419
|
data = await settings.configFetcher(urlWithCache);
|
|
420
|
+
if (data) {
|
|
421
|
+
fetchMethod = 'configFetcher';
|
|
422
|
+
Log.log('[DataConfig] ConfigFetcher success');
|
|
423
|
+
} else {
|
|
424
|
+
Log.debug('[DataConfig] ConfigFetcher returned null, will fallback to axios');
|
|
425
|
+
}
|
|
426
426
|
} catch (e) {
|
|
427
|
-
Log.warn('[DataConfig]
|
|
427
|
+
Log.warn('[DataConfig] ConfigFetcher error, will fallback to axios:', e);
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
|
+
|
|
431
|
+
// 2. Fallback to default axios request
|
|
430
432
|
if (!data) {
|
|
431
|
-
Log.debug('[DataConfig] Trying SDK
|
|
433
|
+
Log.debug('[DataConfig] Trying axios (SDK default fetcher)...');
|
|
432
434
|
try {
|
|
433
435
|
const response = await axios.get<RemoteConfigResponse>(urlWithCache, {
|
|
434
436
|
// because of iframe timeout is 10000
|
|
435
437
|
timeout: 7000,
|
|
436
438
|
});
|
|
437
439
|
data = response.data;
|
|
438
|
-
|
|
440
|
+
fetchMethod = 'axios';
|
|
441
|
+
Log.log('[DataConfig] Axios fetch success');
|
|
439
442
|
} catch (e) {
|
|
440
|
-
Log.warn('[DataConfig]
|
|
443
|
+
Log.warn('[DataConfig] Axios fetch error:', e);
|
|
441
444
|
}
|
|
442
445
|
}
|
|
443
446
|
|
|
447
|
+
// 3. Apply config if available
|
|
444
448
|
if (data) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
449
|
+
const pro2Resources = parseProtocolV2Resources(
|
|
450
|
+
(data.pro2 as { resources?: unknown } | undefined)?.resources
|
|
451
|
+
);
|
|
452
|
+
Log.log(`[DataConfig] Config loaded successfully via [${fetchMethod}]`);
|
|
453
|
+
this.deviceMap = {
|
|
454
|
+
[EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
|
|
455
|
+
[EDeviceType.Classic1s]: this.enrichFirmwareReleaseInfo(data.classic1s),
|
|
456
|
+
[EDeviceType.ClassicPure]: this.enrichFirmwareReleaseInfo(data.classicpure),
|
|
457
|
+
[EDeviceType.Mini]: this.enrichFirmwareReleaseInfo(data.mini),
|
|
458
|
+
[EDeviceType.Touch]: this.enrichFirmwareReleaseInfo(data.touch),
|
|
459
|
+
[EDeviceType.Pro]: this.enrichFirmwareReleaseInfo(data.pro),
|
|
460
|
+
[EDeviceType.Pro2]: {
|
|
461
|
+
...this.enrichFirmwareReleaseInfo(data.pro2),
|
|
462
|
+
...(pro2Resources ? { resources: pro2Resources } : undefined),
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
this.assets = {
|
|
466
|
+
bridge: data.bridge,
|
|
467
|
+
};
|
|
468
|
+
return true;
|
|
448
469
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
private static applyRemoteConfig(data: RemoteConfigResponse) {
|
|
452
|
-
this.deviceMap = {
|
|
453
|
-
[EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
|
|
454
|
-
[EDeviceType.Classic1s]: this.enrichFirmwareReleaseInfo(data.classic1s),
|
|
455
|
-
[EDeviceType.ClassicPure]: this.enrichFirmwareReleaseInfo(data.classicpure),
|
|
456
|
-
[EDeviceType.Mini]: this.enrichFirmwareReleaseInfo(data.mini),
|
|
457
|
-
[EDeviceType.Touch]: this.enrichFirmwareReleaseInfo(data.touch),
|
|
458
|
-
[EDeviceType.Pro]: this.enrichFirmwareReleaseInfo(data.pro),
|
|
459
|
-
[EDeviceType.Pro2]: this.enrichFirmwareReleaseInfo(data.pro2),
|
|
460
|
-
};
|
|
461
|
-
this.assets = {
|
|
462
|
-
bridge: data.bridge,
|
|
463
|
-
};
|
|
470
|
+
Log.warn('[DataConfig] All fetch methods failed, using built-in default config');
|
|
471
|
+
return false;
|
|
464
472
|
}
|
|
465
473
|
|
|
466
474
|
static updateEnv(newEnv: ConnectSettings['env']) {
|
|
@@ -478,10 +486,31 @@ export default class DataManager {
|
|
|
478
486
|
|
|
479
487
|
static async checkAndReloadData() {
|
|
480
488
|
if (getTimeStamp() - this.lastCheckTimestamp > 1000 * 60 * 60 * 3) {
|
|
481
|
-
await this.load(this.settings)
|
|
489
|
+
const loaded = await this.load(this.settings);
|
|
490
|
+
if (loaded) {
|
|
482
491
|
this.lastCheckTimestamp = getTimeStamp();
|
|
483
|
-
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/** Force a fresh remote config before an update is allowed to mutate the device. */
|
|
497
|
+
static async forceReloadData(): Promise<void> {
|
|
498
|
+
if (!this.settings) {
|
|
499
|
+
throw new Error('Remote config settings are not initialized');
|
|
500
|
+
}
|
|
501
|
+
const loaded = await this.load(this.settings);
|
|
502
|
+
if (!loaded) {
|
|
503
|
+
throw new Error('Unable to refresh the latest remote config');
|
|
484
504
|
}
|
|
505
|
+
this.lastCheckTimestamp = getTimeStamp();
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
static getProtocolV2Resources() {
|
|
509
|
+
return this.deviceMap[EDeviceType.Pro2]?.resources?.stable;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
static getProtocolV2BootResources() {
|
|
513
|
+
return this.deviceMap[EDeviceType.Pro2]?.resources?.boot;
|
|
485
514
|
}
|
|
486
515
|
|
|
487
516
|
static getProtobufMessages(schema: ProtobufMessageSchema = 'v1CurrentSchema'): JSON {
|
|
@@ -115,21 +115,10 @@ export const parseConnectSettings = (input: Partial<ConnectSettings> = {}) => {
|
|
|
115
115
|
settings.fetchConfig = input.fetchConfig;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
if (
|
|
119
|
-
input.firmwareManifestMode === 'sdk-managed' ||
|
|
120
|
-
input.firmwareManifestMode === 'external-only'
|
|
121
|
-
) {
|
|
122
|
-
settings.firmwareManifestMode = input.firmwareManifestMode;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
118
|
if (input.configFetcher) {
|
|
126
119
|
settings.configFetcher = input.configFetcher;
|
|
127
120
|
}
|
|
128
121
|
|
|
129
|
-
if (input.preloadedConfig) {
|
|
130
|
-
settings.preloadedConfig = input.preloadedConfig;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
122
|
return settings;
|
|
134
123
|
};
|
|
135
124
|
|