@onekeyfe/hd-core 1.2.0-alpha.67 → 1.2.0-alpha.68
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 +313 -0
- package/__tests__/DeviceCommands.test.ts +59 -13
- package/__tests__/DeviceEventRegistration.test.ts +6 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +198 -3
- package/__tests__/core-initialization.test.ts +23 -0
- package/__tests__/device-connector-protocol.test.ts +81 -0
- package/__tests__/device-lifecycle-events.test.ts +105 -3
- package/__tests__/device-pool-state.test.ts +22 -0
- package/__tests__/device-settings.test.ts +39 -18
- package/__tests__/device-state-contract.test.ts +1 -0
- package/__tests__/device-state-mapper.test.ts +13 -1
- package/__tests__/device-utils.test.ts +48 -1
- package/__tests__/deviceSettings.test.ts +11 -1
- package/__tests__/deviceUploadNft.test.ts +316 -0
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +5 -0
- package/__tests__/get-device-state.test.ts +132 -12
- package/__tests__/homescreen.test.ts +41 -1
- package/__tests__/kaspa-use-tweak-pro2.test.ts +2 -2
- package/__tests__/kaspaSignTransaction.test.ts +3 -26
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +19 -0
- package/__tests__/open-wallet-session.test.ts +568 -37
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/protocol-binding.test.ts +89 -0
- package/__tests__/protocol-v2-resources.test.ts +340 -0
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +300 -37
- package/__tests__/protocol-v2.test.ts +1449 -867
- package/__tests__/protocolV2FileWrite.test.ts +152 -0
- 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__/tron-sign-message-init.test.ts +2 -2
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/__tests__/uiPromiseRegistry.test.ts +115 -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.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +11 -4
- 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/DeviceSettings.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/firmware/FirmwareUpdateBaseMethod.d.ts +4 -3
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +9 -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/kaspa/KaspaGetAddress.d.ts +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotGetAddress.d.ts +1 -1
- package/dist/api/polkadot/networks.d.ts +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/solana/SolSignMessage.d.ts +1 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts +1 -1
- package/dist/api/solana/SolSignTransaction.d.ts +2 -2
- package/dist/api/sui/SuiGetAddress.d.ts +1 -1
- package/dist/api/sui/SuiGetPublicKey.d.ts +1 -1
- package/dist/api/sui/SuiSignMessage.d.ts +1 -1
- package/dist/api/sui/SuiSignTransaction.d.ts +1 -1
- package/dist/api/ton/TonGetAddress.d.ts +1 -1
- package/dist/api/ton/TonSignMessage.d.ts +1 -1
- package/dist/api/ton/TonSignProof.d.ts +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +2 -2
- package/dist/api/tron/TronSignTransaction.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 +6 -0
- package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
- package/dist/data-manager/DataManager.d.ts +9 -3
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.d.ts.map +1 -1
- package/dist/device/Device.d.ts +29 -5
- 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/DeviceConnector.d.ts +2 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/deviceProfile/protocolV2DeviceIdentity.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 +243 -69
- package/dist/index.js +2563 -1217
- 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 +0 -4
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.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 +6 -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 +3 -1
- 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/export.d.ts +1 -0
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +4 -2
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +6 -1
- 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 +2 -2
- 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 +38 -8
- package/dist/types/settings.d.ts.map +1 -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/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/deviceSettings.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 +61 -11
- package/src/api/DetectDeviceConnectProtocol.ts +18 -0
- package/src/api/FirmwareUpdate.ts +6 -2
- package/src/api/FirmwareUpdateV2.ts +5 -2
- package/src/api/FirmwareUpdateV3.ts +6 -2
- package/src/api/FirmwareUpdateV4.ts +463 -258
- package/src/api/GetPassphraseState.ts +7 -1
- package/src/api/OpenWalletSession.ts +71 -17
- package/src/api/SearchDevices.ts +3 -1
- package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +36 -11
- package/src/api/device/DeviceSettings.ts +5 -4
- package/src/api/device/DeviceUnlock.ts +8 -3
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +27 -12
- package/src/api/firmware/uploadFirmware.ts +17 -4
- package/src/api/helpers/protocolV2FileWrite.ts +202 -63
- package/src/api/index.ts +2 -0
- package/src/api/kaspa/KaspaGetAddress.ts +1 -1
- package/src/api/kaspa/KaspaSignTransaction.ts +2 -13
- package/src/api/polkadot/networks.ts +3 -3
- package/src/api/protocol-v2/DeviceUploadNft.ts +197 -0
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
- package/src/api/protocol-v2/helpers.ts +1 -1
- package/src/api/solana/SolSignMessage.ts +1 -1
- package/src/api/solana/SolSignOffchainMessage.ts +1 -1
- package/src/api/solana/SolSignTransaction.ts +2 -2
- package/src/api/sui/SuiGetAddress.ts +1 -1
- package/src/api/sui/SuiGetPublicKey.ts +1 -1
- package/src/api/sui/SuiSignMessage.ts +1 -1
- package/src/api/sui/SuiSignTransaction.ts +1 -1
- package/src/api/ton/TonGetAddress.ts +1 -1
- package/src/api/ton/TonSignMessage.ts +1 -1
- package/src/api/ton/TonSignProof.ts +1 -1
- package/src/api/tron/TronSignMessage.ts +2 -2
- package/src/api/tron/TronSignTransaction.ts +1 -1
- package/src/core/deviceEventRegistration.ts +4 -0
- package/src/core/index.ts +213 -111
- package/src/core/uiPromiseRegistry.ts +63 -0
- package/src/data/messages/messages-protocol-v2.json +25 -0
- package/src/data-manager/DataManager.ts +88 -11
- package/src/data-manager/TransportManager.ts +6 -0
- package/src/device/Device.ts +273 -43
- package/src/device/DeviceCommands.ts +31 -4
- package/src/device/DeviceConnector.ts +33 -13
- package/src/device/DevicePool.ts +21 -7
- package/src/deviceProfile/buildDeviceFeatures.ts +2 -2
- package/src/deviceProfile/protocolV2DeviceIdentity.ts +3 -0
- 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/inject.ts +58 -2
- package/src/lowLevelInject.ts +6 -3
- package/src/protocols/protocol-v2/features.ts +10 -7
- package/src/protocols/protocol-v2/firmware.ts +2 -0
- package/src/protocols/protocol-v2/resources.ts +390 -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 +131 -0
- package/src/protocols/protocol-v2/walletSession.ts +214 -36
- package/src/topLevelInject.ts +6 -3
- package/src/types/api/checkAllFirmwareRelease.ts +3 -1
- package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
- package/src/types/api/deviceUnlock.ts +12 -1
- package/src/types/api/export.ts +1 -0
- package/src/types/api/firmwareUpdate.ts +6 -3
- package/src/types/api/index.ts +13 -0
- package/src/types/api/protocolV2.ts +13 -0
- package/src/types/device.ts +15 -3
- package/src/types/params.ts +7 -1
- package/src/types/settings.ts +60 -9
- package/src/utils/deviceFeaturesCompat.ts +5 -0
- package/src/utils/deviceFeaturesUtils.ts +14 -3
- package/src/utils/deviceInfoUtils.ts +2 -0
- package/src/utils/deviceSettings.ts +3 -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/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/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
|
@@ -0,0 +1,63 @@
|
|
|
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 normalizeUiPromiseError = (error: unknown) =>
|
|
7
|
+
error instanceof Error ? error : new Error(String(error));
|
|
8
|
+
|
|
9
|
+
export const consumeUiPromise = <T>(
|
|
10
|
+
promise: Promise<T>,
|
|
11
|
+
onFulfilled: (value: T) => void,
|
|
12
|
+
onRejected: (error: Error) => void
|
|
13
|
+
) => {
|
|
14
|
+
promise.then(onFulfilled, error => {
|
|
15
|
+
onRejected(normalizeUiPromiseError(error));
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const rejectUiPromises = (
|
|
20
|
+
uiPromises: UiPromise<UiPromiseResponse['type']>[],
|
|
21
|
+
error: Error
|
|
22
|
+
) => {
|
|
23
|
+
for (const uiPromise of uiPromises) {
|
|
24
|
+
uiPromise.reject(error);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const isSensitiveUiResponse = (
|
|
29
|
+
response: UiResponseEvent
|
|
30
|
+
): response is Extract<
|
|
31
|
+
UiResponseEvent,
|
|
32
|
+
{ type: typeof UI_RESPONSE.RECEIVE_PIN | typeof UI_RESPONSE.RECEIVE_PASSPHRASE }
|
|
33
|
+
> => response.type === UI_RESPONSE.RECEIVE_PIN || response.type === UI_RESPONSE.RECEIVE_PASSPHRASE;
|
|
34
|
+
|
|
35
|
+
export const findUiPromiseForResponse = (
|
|
36
|
+
uiPromises: UiPromise<UiPromiseResponse['type']>[],
|
|
37
|
+
response: UiResponseEvent
|
|
38
|
+
) => {
|
|
39
|
+
const candidates = uiPromises.filter(promise => promise.id === response.type);
|
|
40
|
+
if (!isSensitiveUiResponse(response)) {
|
|
41
|
+
return candidates[0];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const hasInteractionId = typeof response.interactionId === 'string';
|
|
45
|
+
const hasDeviceId = typeof response.deviceId === 'string';
|
|
46
|
+
if (hasInteractionId !== hasDeviceId) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (hasInteractionId && hasDeviceId) {
|
|
51
|
+
return candidates.find(promise => {
|
|
52
|
+
const correlation = promise.responseCorrelation;
|
|
53
|
+
return (
|
|
54
|
+
correlation?.interactionId === response.interactionId &&
|
|
55
|
+
correlation?.deviceId === response.deviceId
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Legacy clients do not return correlation metadata. Preserve their single-request
|
|
61
|
+
// behavior, but never guess when multiple sensitive requests are pending.
|
|
62
|
+
return candidates.length === 1 ? candidates[0] : undefined;
|
|
63
|
+
};
|
|
@@ -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,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import semver from 'semver';
|
|
3
|
-
import { EDeviceType, EFirmwareType } from '@onekeyfe/hd-shared';
|
|
3
|
+
import { EDeviceType, EFirmwareType, ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
4
4
|
|
|
5
5
|
import MessagesJSON from '../data/messages/messages.json';
|
|
6
6
|
import MessagesLegacyV1JSON from '../data/messages/messages_legacy_v1.json';
|
|
@@ -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,
|
|
@@ -25,6 +26,7 @@ import type {
|
|
|
25
26
|
Features,
|
|
26
27
|
IDeviceBLEFirmwareStatus,
|
|
27
28
|
IDeviceFirmwareStatus,
|
|
29
|
+
IProtocolV2Resources,
|
|
28
30
|
ITransportStatus,
|
|
29
31
|
IVersionArray,
|
|
30
32
|
RemoteConfigResponse,
|
|
@@ -67,7 +69,7 @@ function getFirmwareTypeFromField(firmwareField: IFirmwareField): EFirmwareType
|
|
|
67
69
|
|
|
68
70
|
export default class DataManager {
|
|
69
71
|
static deviceMap: DeviceTypeMap & {
|
|
70
|
-
[k: string]: DeviceTypeMap[keyof DeviceTypeMap] | undefined;
|
|
72
|
+
[k: string]: NonNullable<DeviceTypeMap[keyof DeviceTypeMap]> | undefined;
|
|
71
73
|
} = {
|
|
72
74
|
[EDeviceType.Classic]: {
|
|
73
75
|
firmware: [],
|
|
@@ -93,6 +95,10 @@ export default class DataManager {
|
|
|
93
95
|
firmware: [],
|
|
94
96
|
ble: [],
|
|
95
97
|
},
|
|
98
|
+
[EDeviceType.Neo]: {
|
|
99
|
+
firmware: [],
|
|
100
|
+
ble: [],
|
|
101
|
+
},
|
|
96
102
|
[EDeviceType.ClassicPure]: {
|
|
97
103
|
firmware: [],
|
|
98
104
|
ble: [],
|
|
@@ -111,6 +117,8 @@ export default class DataManager {
|
|
|
111
117
|
|
|
112
118
|
static lastCheckTimestamp = 0;
|
|
113
119
|
|
|
120
|
+
static protocolV2ResourcesConfigError: Error | undefined;
|
|
121
|
+
|
|
114
122
|
static getFirmwareStatus = (
|
|
115
123
|
features: Features,
|
|
116
124
|
firmwareType: EFirmwareType
|
|
@@ -355,7 +363,7 @@ export default class DataManager {
|
|
|
355
363
|
|
|
356
364
|
private static enrichFirmwareReleaseInfo(
|
|
357
365
|
deviceData: DeviceTypeMap[keyof DeviceTypeMap] | undefined
|
|
358
|
-
): DeviceTypeMap[keyof DeviceTypeMap] {
|
|
366
|
+
): NonNullable<DeviceTypeMap[keyof DeviceTypeMap]> {
|
|
359
367
|
// Safety check: return default structure if input is undefined/null
|
|
360
368
|
if (!deviceData || typeof deviceData !== 'object') {
|
|
361
369
|
return {
|
|
@@ -397,20 +405,21 @@ export default class DataManager {
|
|
|
397
405
|
return enrichedData;
|
|
398
406
|
}
|
|
399
407
|
|
|
400
|
-
static async load(settings: ConnectSettings) {
|
|
408
|
+
static async load(settings: ConnectSettings): Promise<boolean> {
|
|
401
409
|
this.settings = settings;
|
|
410
|
+
this.protocolV2ResourcesConfigError = undefined;
|
|
402
411
|
const manifestMode =
|
|
403
412
|
settings.firmwareManifestMode ?? (settings.fetchConfig ? 'sdk-managed' : undefined);
|
|
404
413
|
if (settings.preloadedConfig) {
|
|
405
414
|
this.applyRemoteConfig(settings.preloadedConfig);
|
|
406
415
|
Log.log('[DataConfig] Preloaded firmware config loaded');
|
|
407
|
-
return;
|
|
416
|
+
return true;
|
|
408
417
|
}
|
|
409
418
|
if (manifestMode === 'external-only') {
|
|
410
419
|
throw new Error('External firmware config snapshot is required');
|
|
411
420
|
}
|
|
412
421
|
if (manifestMode !== 'sdk-managed') {
|
|
413
|
-
return;
|
|
422
|
+
return false;
|
|
414
423
|
}
|
|
415
424
|
|
|
416
425
|
const url = settings.preRelease
|
|
@@ -419,10 +428,14 @@ export default class DataManager {
|
|
|
419
428
|
|
|
420
429
|
const urlWithCache = `${url}?noCache=${getTimeStamp()}`;
|
|
421
430
|
let data: RemoteConfigResponse | null = null;
|
|
431
|
+
let fetchMethod: 'configFetcher' | 'axios' | 'none' = 'none';
|
|
422
432
|
if (settings.configFetcher) {
|
|
423
433
|
Log.debug('[DataConfig] Trying client configFetcher...');
|
|
424
434
|
try {
|
|
425
435
|
data = await settings.configFetcher(urlWithCache);
|
|
436
|
+
if (data) {
|
|
437
|
+
fetchMethod = 'configFetcher';
|
|
438
|
+
}
|
|
426
439
|
} catch (e) {
|
|
427
440
|
Log.warn('[DataConfig] Client configFetcher failed:', e);
|
|
428
441
|
}
|
|
@@ -435,6 +448,7 @@ export default class DataManager {
|
|
|
435
448
|
timeout: 7000,
|
|
436
449
|
});
|
|
437
450
|
data = response.data;
|
|
451
|
+
fetchMethod = 'axios';
|
|
438
452
|
Log.log('[DataConfig] SDK-managed config request succeeded');
|
|
439
453
|
} catch (e) {
|
|
440
454
|
Log.warn('[DataConfig] SDK-managed config request failed:', e);
|
|
@@ -443,12 +457,34 @@ export default class DataManager {
|
|
|
443
457
|
|
|
444
458
|
if (data) {
|
|
445
459
|
this.applyRemoteConfig(data);
|
|
446
|
-
|
|
447
|
-
|
|
460
|
+
Log.log(`[DataConfig] Config loaded successfully via [${fetchMethod}]`);
|
|
461
|
+
return true;
|
|
448
462
|
}
|
|
463
|
+
Log.warn('[DataConfig] All fetch methods failed, using built-in default config');
|
|
464
|
+
return false;
|
|
449
465
|
}
|
|
450
466
|
|
|
451
467
|
private static applyRemoteConfig(data: RemoteConfigResponse) {
|
|
468
|
+
let pro2Resources: IProtocolV2Resources | undefined;
|
|
469
|
+
let neoResources: IProtocolV2Resources | undefined;
|
|
470
|
+
try {
|
|
471
|
+
pro2Resources = parseProtocolV2Resources(
|
|
472
|
+
(data.pro2 as { resources?: unknown } | undefined)?.resources
|
|
473
|
+
);
|
|
474
|
+
neoResources = parseProtocolV2Resources(
|
|
475
|
+
(data.neo as { resources?: unknown } | undefined)?.resources
|
|
476
|
+
);
|
|
477
|
+
} catch (error) {
|
|
478
|
+
// Firmware resource metadata is not required for base communication. If the
|
|
479
|
+
// remote config is temporarily incomplete, disable this resource update only.
|
|
480
|
+
this.protocolV2ResourcesConfigError =
|
|
481
|
+
error instanceof Error ? error : new Error(String(error));
|
|
482
|
+
Log.warn('[DataConfig] Ignoring invalid Protocol V2 resources config:', error);
|
|
483
|
+
}
|
|
484
|
+
const enrichedPro2Config = this.enrichFirmwareReleaseInfo(data.pro2);
|
|
485
|
+
const enrichedNeoConfig = this.enrichFirmwareReleaseInfo(data.neo);
|
|
486
|
+
const { resources: _unvalidatedResources, ...pro2Config } = enrichedPro2Config;
|
|
487
|
+
const { resources: _unvalidatedNeoResources, ...neoConfig } = enrichedNeoConfig;
|
|
452
488
|
this.deviceMap = {
|
|
453
489
|
[EDeviceType.Classic]: this.enrichFirmwareReleaseInfo(data.classic),
|
|
454
490
|
[EDeviceType.Classic1s]: this.enrichFirmwareReleaseInfo(data.classic1s),
|
|
@@ -456,7 +492,14 @@ export default class DataManager {
|
|
|
456
492
|
[EDeviceType.Mini]: this.enrichFirmwareReleaseInfo(data.mini),
|
|
457
493
|
[EDeviceType.Touch]: this.enrichFirmwareReleaseInfo(data.touch),
|
|
458
494
|
[EDeviceType.Pro]: this.enrichFirmwareReleaseInfo(data.pro),
|
|
459
|
-
[EDeviceType.Pro2]:
|
|
495
|
+
[EDeviceType.Pro2]: {
|
|
496
|
+
...pro2Config,
|
|
497
|
+
...(pro2Resources ? { resources: pro2Resources } : undefined),
|
|
498
|
+
},
|
|
499
|
+
[EDeviceType.Neo]: {
|
|
500
|
+
...neoConfig,
|
|
501
|
+
...(neoResources ? { resources: neoResources } : undefined),
|
|
502
|
+
},
|
|
460
503
|
};
|
|
461
504
|
this.assets = {
|
|
462
505
|
bridge: data.bridge,
|
|
@@ -478,12 +521,46 @@ export default class DataManager {
|
|
|
478
521
|
|
|
479
522
|
static async checkAndReloadData() {
|
|
480
523
|
if (getTimeStamp() - this.lastCheckTimestamp > 1000 * 60 * 60 * 3) {
|
|
481
|
-
await this.load(this.settings)
|
|
524
|
+
const loaded = await this.load(this.settings);
|
|
525
|
+
if (loaded) {
|
|
482
526
|
this.lastCheckTimestamp = getTimeStamp();
|
|
483
|
-
}
|
|
527
|
+
}
|
|
484
528
|
}
|
|
485
529
|
}
|
|
486
530
|
|
|
531
|
+
/** Force a fresh remote config before an update is allowed to mutate the device. */
|
|
532
|
+
static async forceReloadData({
|
|
533
|
+
requireResources = false,
|
|
534
|
+
}: { requireResources?: boolean } = {}): Promise<void> {
|
|
535
|
+
if (!this.settings) {
|
|
536
|
+
throw new Error('Remote config settings are not initialized');
|
|
537
|
+
}
|
|
538
|
+
const loaded = await this.load(this.settings);
|
|
539
|
+
if (!loaded) {
|
|
540
|
+
throw ERRORS.TypedError(
|
|
541
|
+
HardwareErrorCode.NetworkError,
|
|
542
|
+
'Unable to refresh the latest remote config'
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
if (requireResources && this.protocolV2ResourcesConfigError) {
|
|
546
|
+
throw ERRORS.TypedError(
|
|
547
|
+
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
548
|
+
`Invalid Pro2 resources config: ${this.protocolV2ResourcesConfigError.message}`
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
this.lastCheckTimestamp = getTimeStamp();
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
static getProtocolV2Resources(deviceType: EDeviceType.Pro2 | EDeviceType.Neo = EDeviceType.Pro2) {
|
|
555
|
+
return this.deviceMap[deviceType]?.resources?.stable;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
static getProtocolV2BootResources(
|
|
559
|
+
deviceType: EDeviceType.Pro2 | EDeviceType.Neo = EDeviceType.Pro2
|
|
560
|
+
) {
|
|
561
|
+
return this.deviceMap[deviceType]?.resources?.boot;
|
|
562
|
+
}
|
|
563
|
+
|
|
487
564
|
static getProtobufMessages(schema: ProtobufMessageSchema = 'v1CurrentSchema'): JSON {
|
|
488
565
|
return this.messages[schema];
|
|
489
566
|
}
|
|
@@ -121,6 +121,12 @@ export default class TransportManager {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
static setTransport(TransportConstructor: any, plugin?: LowlevelTransportSharedPlugin) {
|
|
124
|
+
if (typeof TransportConstructor !== 'function') {
|
|
125
|
+
throw ERRORS.TypedError(
|
|
126
|
+
HardwareErrorCode.TransportNotConfigured,
|
|
127
|
+
'Transport constructor is not available'
|
|
128
|
+
);
|
|
129
|
+
}
|
|
124
130
|
const env = DataManager.getSettings('env');
|
|
125
131
|
if (env === 'react-native') {
|
|
126
132
|
/** Actually initializes the ReactNativeTransport */
|