@onekeyfe/hd-core 1.2.0-alpha.67 → 1.2.0-alpha.69
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 +226 -3
- package/__tests__/connectSettings.test.ts +5 -47
- 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-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__/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-firmware-targets.test.ts +33 -1
- package/__tests__/protocol-v2-resources.test.ts +343 -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 +1586 -1213
- package/__tests__/protocolV2FileWrite.test.ts +193 -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 +3 -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 -10
- 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 +15 -27
- 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/device/DeviceUpdateBootloader.d.ts +1 -5
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -11
- 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 +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/stellar/StellarSignTransaction.d.ts +1 -1
- 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 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.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/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 -247
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3135 -3785
- 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 -5
- 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 +4 -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 +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 -21
- 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/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 +78 -64
- package/src/api/DetectDeviceConnectProtocol.ts +18 -0
- package/src/api/FirmwareUpdate.ts +7 -15
- package/src/api/FirmwareUpdateV2.ts +126 -298
- package/src/api/FirmwareUpdateV3.ts +63 -265
- package/src/api/FirmwareUpdateV4.ts +645 -1018
- 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/device/DeviceUpdateBootloader.ts +6 -125
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +27 -83
- package/src/api/firmware/updateBootloader.ts +4 -19
- package/src/api/firmware/uploadFirmware.ts +39 -144
- package/src/api/helpers/protocolV2FileWrite.ts +252 -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 +113 -41
- package/src/data-manager/TransportManager.ts +6 -0
- package/src/data-manager/connectSettings.ts +0 -11
- package/src/device/Device.ts +274 -49
- 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/index.ts +0 -5
- package/src/inject.ts +60 -24
- package/src/lowLevelInject.ts +7 -8
- 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 +394 -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 +7 -8
- package/src/types/api/checkAllFirmwareRelease.ts +3 -5
- package/src/types/api/detectDeviceConnectProtocol.ts +6 -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 +6 -78
- package/src/types/api/index.ts +13 -14
- 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 +61 -22
- package/src/utils/deviceFeaturesCompat.ts +5 -6
- 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/__tests__/device-initialize-timeout.test.ts +0 -56
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
- package/__tests__/firmware-update/device-update-bootloader.test.ts +0 -87
- 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 -394
- package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -231
- 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 -449
- 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
|
@@ -5,6 +5,7 @@ import CheckAllFirmwareRelease, {
|
|
|
5
5
|
} from '../src/api/CheckAllFirmwareRelease';
|
|
6
6
|
import { DataManager } from '../src/data-manager';
|
|
7
7
|
import { createCoreApi } from '../src/inject';
|
|
8
|
+
import { PROTOCOL_V2_RESOURCE_DEVICE_PATHS } from '../src/protocols/protocol-v2/resources';
|
|
8
9
|
|
|
9
10
|
import type { CoreApi } from '../src/types/api';
|
|
10
11
|
import type { DeviceStateVersions, IFirmwareReleaseInfo } from '../src/types';
|
|
@@ -72,7 +73,74 @@ const release: IFirmwareReleaseInfo = {
|
|
|
72
73
|
],
|
|
73
74
|
};
|
|
74
75
|
|
|
76
|
+
const stableResources = ['images', 'animation', 'wallpaper', 'translations', 'roobert', 'noto'].map(
|
|
77
|
+
(type, index) => ({
|
|
78
|
+
type,
|
|
79
|
+
url: `https://example.com/${type}.okpkg`,
|
|
80
|
+
size: 0x52a0 + index + 1,
|
|
81
|
+
fileHash: 'a'.repeat(64),
|
|
82
|
+
headerHash: index.toString(16).padStart(128, '0'),
|
|
83
|
+
})
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const createFilesystemTypedCall = (missingAll = false) => {
|
|
87
|
+
const resourceByPath = new Map(
|
|
88
|
+
stableResources.map(resource => [
|
|
89
|
+
PROTOCOL_V2_RESOURCE_DEVICE_PATHS[
|
|
90
|
+
resource.type as keyof typeof PROTOCOL_V2_RESOURCE_DEVICE_PATHS
|
|
91
|
+
],
|
|
92
|
+
resource,
|
|
93
|
+
])
|
|
94
|
+
);
|
|
95
|
+
return jest.fn((requestType: string, _responseType: string, payload: Record<string, any>) => {
|
|
96
|
+
if (requestType === 'ResourceInventoryGet') {
|
|
97
|
+
throw new Error('ResourceInventoryGet is unavailable on released firmware');
|
|
98
|
+
}
|
|
99
|
+
if (requestType === 'FilesystemPathInfoQuery') {
|
|
100
|
+
const resource = resourceByPath.get(payload.path);
|
|
101
|
+
return {
|
|
102
|
+
message: {
|
|
103
|
+
exist: Boolean(resource) && !missingAll,
|
|
104
|
+
directory: false,
|
|
105
|
+
size: missingAll ? 0 : resource?.size,
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (requestType === 'FilesystemFileRead') {
|
|
110
|
+
const resource = resourceByPath.get(payload.file.path);
|
|
111
|
+
if (!resource || missingAll) throw new Error('missing resource');
|
|
112
|
+
const header = new Uint8Array(0x52a0);
|
|
113
|
+
const view = new DataView(header.buffer);
|
|
114
|
+
'OKPP'.split('').forEach((char, index) => {
|
|
115
|
+
header[index] = char.charCodeAt(0);
|
|
116
|
+
});
|
|
117
|
+
'RESC'.split('').forEach((char, index) => {
|
|
118
|
+
header[0x08 + index] = char.charCodeAt(0);
|
|
119
|
+
});
|
|
120
|
+
view.setUint32(0x0c, header.byteLength, true);
|
|
121
|
+
for (let index = 0; index < resource.headerHash.length / 2; index++) {
|
|
122
|
+
header[0x240 + index] = Number.parseInt(
|
|
123
|
+
resource.headerHash.slice(index * 2, index * 2 + 2),
|
|
124
|
+
16
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
const offset = Number(payload.file.offset);
|
|
128
|
+
const chunkLength = Number(payload.chunk_len);
|
|
129
|
+
return {
|
|
130
|
+
message: {
|
|
131
|
+
data: header.slice(offset, offset + chunkLength),
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`Unexpected request: ${requestType}`);
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
|
|
75
139
|
describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
140
|
+
afterEach(() => {
|
|
141
|
+
jest.restoreAllMocks();
|
|
142
|
+
});
|
|
143
|
+
|
|
76
144
|
test('builds ordered firmwareUpdateV4 targets from recommended component versions', () => {
|
|
77
145
|
const result = buildProtocolV2FirmwareRelease({
|
|
78
146
|
currentVersions,
|
|
@@ -84,7 +152,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
84
152
|
status: 'required',
|
|
85
153
|
hasUpgrade: true,
|
|
86
154
|
required: true,
|
|
87
|
-
targetsToUpdate: ['boot', 'app_v1'
|
|
155
|
+
targetsToUpdate: ['boot', 'app_v1'],
|
|
88
156
|
components: [
|
|
89
157
|
{ configKey: 'bootloader', status: 'outdated', updateTarget: 'boot' },
|
|
90
158
|
{ configKey: 'applicationP1', status: 'outdated', updateTarget: 'app_v1' },
|
|
@@ -95,6 +163,34 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
95
163
|
});
|
|
96
164
|
});
|
|
97
165
|
|
|
166
|
+
test('marks SE03 and SE04 as unsupported in a Neo firmware plan', () => {
|
|
167
|
+
const neoRelease: IFirmwareReleaseInfo = {
|
|
168
|
+
...release,
|
|
169
|
+
installOrder: ['se01', 'se02', 'se03', 'se04'],
|
|
170
|
+
components: {
|
|
171
|
+
se01: { target: 'SE01', url: 'https://example.com/se01.bin', version: [2, 0, 0] },
|
|
172
|
+
se02: { target: 'SE02', url: 'https://example.com/se02.bin', version: [3, 0, 0] },
|
|
173
|
+
se03: { target: 'SE03', url: 'https://example.com/se03.bin', version: [2, 0, 0] },
|
|
174
|
+
se04: { target: 'SE04', url: 'https://example.com/se04.bin', version: [2, 0, 0] },
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const result = buildProtocolV2FirmwareRelease({
|
|
179
|
+
currentVersions,
|
|
180
|
+
firmwareType: EFirmwareType.Universal,
|
|
181
|
+
release: neoRelease,
|
|
182
|
+
deviceType: 'neo',
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(result.targetsToUpdate).toEqual(['se01', 'se02']);
|
|
186
|
+
expect(result.components).toEqual(
|
|
187
|
+
expect.arrayContaining([
|
|
188
|
+
expect.objectContaining({ configKey: 'se03', status: 'unsupported', updateTarget: null }),
|
|
189
|
+
expect.objectContaining({ configKey: 'se04', status: 'unsupported', updateTarget: null }),
|
|
190
|
+
])
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
98
194
|
test('returns an unavailable plan when no Pro2 release is configured', () => {
|
|
99
195
|
expect(
|
|
100
196
|
buildProtocolV2FirmwareRelease({
|
|
@@ -142,6 +238,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
142
238
|
applicationP1Hash: 'aa'.repeat(32),
|
|
143
239
|
applicationP2Hash: 'bb'.repeat(32),
|
|
144
240
|
},
|
|
241
|
+
checkFirmwareHash: true,
|
|
145
242
|
remotePayloadHashes: {
|
|
146
243
|
applicationP1: 'aa'.repeat(64),
|
|
147
244
|
applicationP2: 'cc'.repeat(64),
|
|
@@ -160,6 +257,37 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
160
257
|
});
|
|
161
258
|
});
|
|
162
259
|
|
|
260
|
+
test('uses version-only comparison for same-version packages by default', () => {
|
|
261
|
+
const packageSet: IFirmwareReleaseInfo = {
|
|
262
|
+
...release,
|
|
263
|
+
required: false,
|
|
264
|
+
resourceBundles: undefined,
|
|
265
|
+
installOrder: ['applicationP1'],
|
|
266
|
+
components: {
|
|
267
|
+
applicationP1: {
|
|
268
|
+
target: 'APPLICATION_P1',
|
|
269
|
+
version: [1, 0, 0],
|
|
270
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
271
|
+
payloadHash: 'cc'.repeat(64),
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
expect(
|
|
277
|
+
buildProtocolV2FirmwareRelease({
|
|
278
|
+
currentVersions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
279
|
+
currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
280
|
+
firmwareType: EFirmwareType.Universal,
|
|
281
|
+
release: packageSet,
|
|
282
|
+
})
|
|
283
|
+
).toMatchObject({
|
|
284
|
+
status: 'valid',
|
|
285
|
+
hasUpgrade: false,
|
|
286
|
+
targetsToUpdate: [],
|
|
287
|
+
components: [{ configKey: 'applicationP1', status: 'valid' }],
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
|
|
163
291
|
test('keeps same-version hash-aware components unknown without metadata payloadHash', () => {
|
|
164
292
|
const packageSet: IFirmwareReleaseInfo = {
|
|
165
293
|
...release,
|
|
@@ -180,6 +308,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
180
308
|
buildProtocolV2FirmwareRelease({
|
|
181
309
|
currentVersions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
182
310
|
currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
311
|
+
checkFirmwareHash: true,
|
|
183
312
|
firmwareType: EFirmwareType.Universal,
|
|
184
313
|
release: packageSet,
|
|
185
314
|
})
|
|
@@ -215,6 +344,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
215
344
|
const result = buildProtocolV2FirmwareRelease({
|
|
216
345
|
currentVersions,
|
|
217
346
|
currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
347
|
+
checkFirmwareHash: true,
|
|
218
348
|
remotePayloadHashes: { applicationP1: 'cc'.repeat(64) },
|
|
219
349
|
firmwareType: EFirmwareType.Universal,
|
|
220
350
|
release: packageSet,
|
|
@@ -223,7 +353,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
223
353
|
expect(result.targetsToUpdate).toEqual(['app_v1', 'app_v2']);
|
|
224
354
|
});
|
|
225
355
|
|
|
226
|
-
test('
|
|
356
|
+
test('does not read vol0 resource inventory while Protocol V2 is in Application mode', async () => {
|
|
227
357
|
const method = new CheckAllFirmwareRelease({
|
|
228
358
|
id: 1,
|
|
229
359
|
payload: {
|
|
@@ -240,6 +370,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
240
370
|
status: { mode: 'normal' },
|
|
241
371
|
versions: currentVersions,
|
|
242
372
|
});
|
|
373
|
+
const typedCall = createFilesystemTypedCall(true);
|
|
243
374
|
method.device = {
|
|
244
375
|
isProtocolV2: () => true,
|
|
245
376
|
features: {
|
|
@@ -247,32 +378,124 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
247
378
|
firmwareVersion: '1.0.0',
|
|
248
379
|
},
|
|
249
380
|
getDeviceState,
|
|
381
|
+
getCommands: () => ({ typedCall }),
|
|
250
382
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
251
383
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
384
|
+
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
|
|
252
385
|
|
|
253
386
|
await expect(method.run()).resolves.toMatchObject({
|
|
254
387
|
protocol: 'V2',
|
|
255
388
|
deviceType: 'pro2',
|
|
256
389
|
status: 'required',
|
|
257
|
-
|
|
390
|
+
resourceStatus: 'unknown',
|
|
391
|
+
targetsToUpdate: ['boot', 'app_v1'],
|
|
258
392
|
firmware: {
|
|
259
393
|
status: 'required',
|
|
260
394
|
},
|
|
261
395
|
});
|
|
396
|
+
expect(typedCall).not.toHaveBeenCalled();
|
|
397
|
+
expect(getDeviceState).toHaveBeenCalledWith({
|
|
398
|
+
refreshSections: ['identity', 'versions'],
|
|
399
|
+
});
|
|
262
400
|
expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
263
401
|
});
|
|
264
402
|
|
|
403
|
+
test('requests and compares firmware hashes only when explicitly enabled', async () => {
|
|
404
|
+
const packageSet: IFirmwareReleaseInfo = {
|
|
405
|
+
...release,
|
|
406
|
+
required: false,
|
|
407
|
+
resourceBundles: undefined,
|
|
408
|
+
installOrder: ['applicationP1'],
|
|
409
|
+
components: {
|
|
410
|
+
applicationP1: {
|
|
411
|
+
target: 'APPLICATION_P1',
|
|
412
|
+
version: [1, 0, 0],
|
|
413
|
+
url: 'https://example.com/application-p1.okpkg',
|
|
414
|
+
payloadHash: 'cc'.repeat(64),
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
const method = new CheckAllFirmwareRelease({
|
|
419
|
+
id: 1,
|
|
420
|
+
payload: {
|
|
421
|
+
method: 'checkAllFirmwareRelease',
|
|
422
|
+
firmwareType: EFirmwareType.Universal,
|
|
423
|
+
checkFirmwareHash: true,
|
|
424
|
+
},
|
|
425
|
+
});
|
|
426
|
+
method.init();
|
|
427
|
+
const getDeviceState = jest.fn().mockResolvedValue({
|
|
428
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
429
|
+
status: { mode: 'normal' },
|
|
430
|
+
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
431
|
+
verification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
432
|
+
});
|
|
433
|
+
method.device = {
|
|
434
|
+
isProtocolV2: () => true,
|
|
435
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
436
|
+
getDeviceState,
|
|
437
|
+
getCommands: () => ({ typedCall: jest.fn() }),
|
|
438
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
439
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(packageSet);
|
|
440
|
+
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(undefined);
|
|
441
|
+
|
|
442
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
443
|
+
status: 'outdated',
|
|
444
|
+
targetsToUpdate: ['app_v1'],
|
|
445
|
+
});
|
|
446
|
+
expect(getDeviceState).toHaveBeenCalledWith({
|
|
447
|
+
refreshSections: ['identity', 'versions', 'verification'],
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
test.each(['bootloader', 'romloader'] as const)(
|
|
452
|
+
'uses filesystem inventory in %s mode instead of forcing all resources',
|
|
453
|
+
async mode => {
|
|
454
|
+
const method = new CheckAllFirmwareRelease({
|
|
455
|
+
id: 1,
|
|
456
|
+
payload: {
|
|
457
|
+
method: 'checkAllFirmwareRelease',
|
|
458
|
+
firmwareType: EFirmwareType.Universal,
|
|
459
|
+
},
|
|
460
|
+
});
|
|
461
|
+
method.init();
|
|
462
|
+
const typedCall = createFilesystemTypedCall();
|
|
463
|
+
method.device = {
|
|
464
|
+
isProtocolV2: () => true,
|
|
465
|
+
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
466
|
+
getDeviceState: jest.fn().mockResolvedValue({
|
|
467
|
+
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
468
|
+
status: { mode },
|
|
469
|
+
versions: currentVersions,
|
|
470
|
+
}),
|
|
471
|
+
getCommands: () => ({ typedCall }),
|
|
472
|
+
} as unknown as CheckAllFirmwareRelease['device'];
|
|
473
|
+
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
474
|
+
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
|
|
475
|
+
|
|
476
|
+
await expect(method.run()).resolves.toMatchObject({
|
|
477
|
+
protocol: 'V2',
|
|
478
|
+
resourceStatus: 'valid',
|
|
479
|
+
targetsToUpdate: ['boot', 'app_v1'],
|
|
480
|
+
});
|
|
481
|
+
expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
|
|
482
|
+
expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
|
|
265
486
|
test('continues forwarding the existing public method', async () => {
|
|
266
487
|
const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
|
|
267
488
|
const api = createCoreApi(call as CoreApi['call']) as CoreApi;
|
|
268
489
|
|
|
269
490
|
await api.checkAllFirmwareRelease('pro2-connect-id', {
|
|
491
|
+
checkFirmwareHash: true,
|
|
270
492
|
firmwareType: EFirmwareType.Universal,
|
|
271
493
|
retryCount: 0,
|
|
272
494
|
});
|
|
273
495
|
|
|
274
496
|
expect(call).toHaveBeenCalledWith({
|
|
275
497
|
connectId: 'pro2-connect-id',
|
|
498
|
+
checkFirmwareHash: true,
|
|
276
499
|
firmwareType: EFirmwareType.Universal,
|
|
277
500
|
retryCount: 0,
|
|
278
501
|
method: 'checkAllFirmwareRelease',
|
|
@@ -1,61 +1,19 @@
|
|
|
1
|
-
import DataManager from '../src/data-manager/DataManager';
|
|
2
1
|
import { parseConnectSettings } from '../src/data-manager/connectSettings';
|
|
3
2
|
|
|
4
|
-
import type { RemoteConfigResponse } from '../src/types';
|
|
5
|
-
|
|
6
|
-
jest.mock('axios', () => ({
|
|
7
|
-
get: jest.fn(),
|
|
8
|
-
}));
|
|
9
|
-
|
|
10
3
|
jest.mock('../src/data/config', () => ({
|
|
11
4
|
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
12
5
|
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
13
6
|
}));
|
|
14
7
|
|
|
15
|
-
const mockAxiosGet: jest.Mock = jest.requireMock('axios').get;
|
|
16
|
-
|
|
17
8
|
describe('parseConnectSettings', () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
classic: { firmware: [], ble: [] },
|
|
21
|
-
classic1s: { firmware: [], ble: [] },
|
|
22
|
-
classicpure: { firmware: [], ble: [] },
|
|
23
|
-
mini: { firmware: [], ble: [] },
|
|
24
|
-
touch: { firmware: [], ble: [] },
|
|
25
|
-
pro: { firmware: [], ble: [] },
|
|
26
|
-
pro2: { firmware: [], ble: [] },
|
|
27
|
-
} as unknown as RemoteConfigResponse;
|
|
28
|
-
|
|
29
|
-
it('keeps a serializable preloaded config in parsed settings', () => {
|
|
30
|
-
const settings = parseConnectSettings({
|
|
31
|
-
firmwareManifestMode: 'sdk-managed',
|
|
32
|
-
preloadedConfig,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
expect(settings.firmwareManifestMode).toBe('sdk-managed');
|
|
36
|
-
expect(settings.preloadedConfig).toBe(preloadedConfig);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('uses the preloaded config before the SDK network client', async () => {
|
|
40
|
-
const settings = parseConnectSettings({
|
|
41
|
-
firmwareManifestMode: 'sdk-managed',
|
|
42
|
-
preloadedConfig,
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
await DataManager.load(settings);
|
|
46
|
-
|
|
47
|
-
expect(mockAxiosGet).not.toHaveBeenCalled();
|
|
48
|
-
expect(DataManager.deviceMap.classic).toEqual({ firmware: [], ble: [] });
|
|
49
|
-
});
|
|
9
|
+
it('keeps custom configFetcher in parsed settings', () => {
|
|
10
|
+
const configFetcher = jest.fn();
|
|
50
11
|
|
|
51
|
-
it('fails closed without a preloaded config in external-only mode', async () => {
|
|
52
12
|
const settings = parseConnectSettings({
|
|
53
|
-
|
|
13
|
+
fetchConfig: true,
|
|
14
|
+
configFetcher,
|
|
54
15
|
});
|
|
55
16
|
|
|
56
|
-
|
|
57
|
-
'External firmware config snapshot is required'
|
|
58
|
-
);
|
|
59
|
-
expect(mockAxiosGet).not.toHaveBeenCalled();
|
|
17
|
+
expect(settings.configFetcher).toBe(configFetcher);
|
|
60
18
|
});
|
|
61
19
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DataManager } from '../src/data-manager';
|
|
2
|
+
import { init } from '../src/core';
|
|
3
|
+
|
|
4
|
+
import type { ConnectSettings } from '../src/types';
|
|
5
|
+
|
|
6
|
+
jest.mock('../src/data/config', () => ({
|
|
7
|
+
getSDKVersion: jest.fn(() => '1.0.0-test'),
|
|
8
|
+
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0-test/',
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
describe('Core initialization', () => {
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
jest.restoreAllMocks();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('does not create a partially initialized core when settings loading fails', async () => {
|
|
17
|
+
jest.spyOn(DataManager, 'load').mockRejectedValue(new Error('settings load failed'));
|
|
18
|
+
|
|
19
|
+
await expect(init({} as ConnectSettings, class TestTransport {})).rejects.toThrow(
|
|
20
|
+
'settings load failed'
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import DeviceConnector from '../src/device/DeviceConnector';
|
|
4
|
+
|
|
5
|
+
jest.mock('../src/data-manager/TransportManager', () => ({
|
|
6
|
+
__esModule: true,
|
|
7
|
+
default: {
|
|
8
|
+
load: jest.fn(),
|
|
9
|
+
getTransport: jest.fn(),
|
|
10
|
+
},
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('../src/data-manager', () => ({
|
|
14
|
+
DataManager: {
|
|
15
|
+
getSettings: jest.fn(() => 'desktop-web-ble'),
|
|
16
|
+
isBleConnect: jest.fn(() => true),
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
jest.mock('../src/device/DevicePool', () => ({
|
|
21
|
+
DevicePool: {
|
|
22
|
+
setConnector: jest.fn(),
|
|
23
|
+
},
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
const transportManagerMock: {
|
|
27
|
+
default: {
|
|
28
|
+
getTransport: jest.Mock;
|
|
29
|
+
};
|
|
30
|
+
} = jest.requireMock('../src/data-manager/TransportManager');
|
|
31
|
+
|
|
32
|
+
describe('DeviceConnector protocol validation', () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('reports an explicit transport error when connector initialization ran too early', async () => {
|
|
38
|
+
transportManagerMock.default.getTransport.mockReturnValue(undefined);
|
|
39
|
+
const connector = new DeviceConnector();
|
|
40
|
+
|
|
41
|
+
await expect(connector.enumerate()).rejects.toMatchObject({
|
|
42
|
+
errorCode: HardwareErrorCode.TransportNotConfigured,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('uses the actively probed protocol returned by acquire when the cache was cleared', async () => {
|
|
47
|
+
const acquire = jest.fn().mockResolvedValue({
|
|
48
|
+
id: 'pro2-id',
|
|
49
|
+
path: 'pro2-id',
|
|
50
|
+
protocolType: 'V2',
|
|
51
|
+
});
|
|
52
|
+
transportManagerMock.default.getTransport.mockReturnValue({
|
|
53
|
+
acquire,
|
|
54
|
+
getProtocolType: jest.fn(() => undefined),
|
|
55
|
+
});
|
|
56
|
+
const connector = new DeviceConnector();
|
|
57
|
+
|
|
58
|
+
await expect(connector.acquire('pro2-id', undefined, undefined, 'V2')).resolves.toEqual(
|
|
59
|
+
expect.objectContaining({ protocolType: 'V2' })
|
|
60
|
+
);
|
|
61
|
+
expect(acquire).toHaveBeenCalledWith(
|
|
62
|
+
expect.objectContaining({ uuid: 'pro2-id', expectedProtocol: 'V2' })
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('still rejects a real mismatch reported by the active protocol probe', async () => {
|
|
67
|
+
transportManagerMock.default.getTransport.mockReturnValue({
|
|
68
|
+
acquire: jest.fn().mockResolvedValue({
|
|
69
|
+
id: 'classic-id',
|
|
70
|
+
path: 'classic-id',
|
|
71
|
+
protocolType: 'V1',
|
|
72
|
+
}),
|
|
73
|
+
getProtocolType: jest.fn(() => 'V1'),
|
|
74
|
+
});
|
|
75
|
+
const connector = new DeviceConnector();
|
|
76
|
+
|
|
77
|
+
await expect(connector.acquire('classic-id', undefined, undefined, 'V2')).rejects.toThrow(
|
|
78
|
+
'Device protocol mismatch: expected V2, detected V1'
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
1
2
|
import { TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
|
|
2
3
|
|
|
3
4
|
import { initConnector, initCore } from '../src/core';
|
|
@@ -95,7 +96,7 @@ describe('public device lifecycle events', () => {
|
|
|
95
96
|
expect(messages.filter(message => message.type === DEVICE.DISCONNECT)).toHaveLength(1);
|
|
96
97
|
});
|
|
97
98
|
|
|
98
|
-
test('uses a cached protocol as a
|
|
99
|
+
test('uses a verified cached protocol as a strict expected protocol', async () => {
|
|
99
100
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
100
101
|
const device = Device.fromDescriptor({
|
|
101
102
|
id: 'ble-id',
|
|
@@ -103,16 +104,117 @@ describe('public device lifecycle events', () => {
|
|
|
103
104
|
commType: 'ble',
|
|
104
105
|
protocolType: 'V1',
|
|
105
106
|
} as never);
|
|
106
|
-
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: '
|
|
107
|
+
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V1' });
|
|
107
108
|
device.deviceConnector = { acquire } as never;
|
|
108
109
|
|
|
109
110
|
await device.acquire();
|
|
110
111
|
|
|
111
|
-
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true,
|
|
112
|
+
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, 'V1', undefined);
|
|
113
|
+
expect(device.getProtocol()).toBe('V1');
|
|
114
|
+
expect(device.originalDescriptor.protocolType).toBe('V1');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('bypasses a cached protocol only for explicit active detection', async () => {
|
|
118
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
119
|
+
const device = Device.fromDescriptor({
|
|
120
|
+
id: 'ble-id',
|
|
121
|
+
path: 'ble-id',
|
|
122
|
+
commType: 'ble',
|
|
123
|
+
protocolType: 'V1',
|
|
124
|
+
} as never);
|
|
125
|
+
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V2' });
|
|
126
|
+
device.deviceConnector = { acquire } as never;
|
|
127
|
+
|
|
128
|
+
await device.acquire(undefined, { forceProtocolDetection: true });
|
|
129
|
+
|
|
130
|
+
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, undefined, undefined);
|
|
112
131
|
expect(device.getProtocol()).toBe('V2');
|
|
113
132
|
expect(device.originalDescriptor.protocolType).toBe('V2');
|
|
114
133
|
});
|
|
115
134
|
|
|
135
|
+
test('does not reuse a stale protocol when active detection returns no protocol', async () => {
|
|
136
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
137
|
+
const device = Device.fromDescriptor({
|
|
138
|
+
id: 'ble-id',
|
|
139
|
+
path: 'ble-id',
|
|
140
|
+
commType: 'ble',
|
|
141
|
+
protocolType: 'V1',
|
|
142
|
+
} as never);
|
|
143
|
+
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id' });
|
|
144
|
+
const release = jest.fn().mockResolvedValue(undefined);
|
|
145
|
+
device.deviceConnector = { acquire, release } as never;
|
|
146
|
+
await expect(
|
|
147
|
+
device.acquire(undefined, {
|
|
148
|
+
forceProtocolDetection: true,
|
|
149
|
+
throwOnRunPromiseError: true,
|
|
150
|
+
})
|
|
151
|
+
).rejects.toMatchObject({ errorCode: HardwareErrorCode.RuntimeError });
|
|
152
|
+
expect(device.originalDescriptor.protocolType).toBe('V1');
|
|
153
|
+
expect(device.hasDeviceAcquire()).toBe(false);
|
|
154
|
+
expect(release).toHaveBeenCalledWith('ble-id', false);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
test('actively reacquires an already connected device without initializing it', async () => {
|
|
158
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('webusb' as never);
|
|
159
|
+
const device = Device.fromDescriptor({
|
|
160
|
+
id: 'usb-device',
|
|
161
|
+
path: 'usb-device',
|
|
162
|
+
session: 'old-session',
|
|
163
|
+
protocolType: 'V1',
|
|
164
|
+
} as never);
|
|
165
|
+
device.mainId = 'old-session';
|
|
166
|
+
device.commands = { disposed: false } as never;
|
|
167
|
+
const release = jest.spyOn(device, 'release').mockImplementation(() => {
|
|
168
|
+
device.mainId = null;
|
|
169
|
+
device.originalDescriptor.session = null;
|
|
170
|
+
device.commands.disposed = true;
|
|
171
|
+
return Promise.resolve();
|
|
172
|
+
});
|
|
173
|
+
const acquire = jest.spyOn(device, 'acquire').mockImplementation(() => {
|
|
174
|
+
device.mainId = 'new-session';
|
|
175
|
+
device.originalDescriptor.session = 'new-session';
|
|
176
|
+
device.originalDescriptor.protocolType = 'V2';
|
|
177
|
+
device.commands.disposed = false;
|
|
178
|
+
return Promise.resolve();
|
|
179
|
+
});
|
|
180
|
+
const initialize = jest.spyOn(device, 'initialize').mockResolvedValue(undefined);
|
|
181
|
+
|
|
182
|
+
await device.run(() => Promise.resolve(undefined), {
|
|
183
|
+
forceProtocolDetection: true,
|
|
184
|
+
skipInitialize: true,
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
expect(release).toHaveBeenCalled();
|
|
188
|
+
expect(acquire).toHaveBeenCalledWith(undefined, {
|
|
189
|
+
forceProtocolDetection: true,
|
|
190
|
+
});
|
|
191
|
+
expect(initialize).not.toHaveBeenCalled();
|
|
192
|
+
expect(device.getProtocol()).toBe('V2');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('keeps the freshly probed React Native BLE session until the call completes', async () => {
|
|
196
|
+
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
197
|
+
const device = Device.fromDescriptor({
|
|
198
|
+
id: 'ble-device',
|
|
199
|
+
path: 'ble-device',
|
|
200
|
+
commType: 'ble',
|
|
201
|
+
protocolType: 'V1',
|
|
202
|
+
} as never);
|
|
203
|
+
device.mainId = 'ble-device';
|
|
204
|
+
device.commands = { disposed: false } as never;
|
|
205
|
+
(device as unknown as { deviceAcquired: boolean }).deviceAcquired = true;
|
|
206
|
+
const release = jest.spyOn(device, 'release').mockResolvedValue(undefined);
|
|
207
|
+
const run = jest.fn().mockResolvedValue(undefined);
|
|
208
|
+
|
|
209
|
+
await device.run(run, {
|
|
210
|
+
forceProtocolDetection: true,
|
|
211
|
+
skipInitialize: true,
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
expect(run).toHaveBeenCalledTimes(1);
|
|
215
|
+
expect(release).toHaveBeenCalledTimes(1);
|
|
216
|
+
});
|
|
217
|
+
|
|
116
218
|
test('keeps an explicit connectProtocol as a strict expected protocol', async () => {
|
|
117
219
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
118
220
|
const device = Device.fromDescriptor({
|
|
@@ -38,6 +38,28 @@ describe('DevicePool state lifecycle', () => {
|
|
|
38
38
|
expect(getDeviceState).toHaveBeenNthCalledWith(2, { refreshSections: ['settings'] });
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
+
test('actively re-detects a cached device when protocol detection is forced', async () => {
|
|
42
|
+
const descriptor = { path: 'cached-path', protocolType: 'V1' } as any;
|
|
43
|
+
const device = Device.fromDescriptor(descriptor);
|
|
44
|
+
const acquire = jest.spyOn(device, 'acquire').mockImplementation(() => {
|
|
45
|
+
device.originalDescriptor.protocolType = 'V2';
|
|
46
|
+
return Promise.resolve(true);
|
|
47
|
+
});
|
|
48
|
+
const initialize = jest.spyOn(device, 'initialize').mockResolvedValue(undefined);
|
|
49
|
+
const release = jest.spyOn(device, 'release').mockResolvedValue(undefined);
|
|
50
|
+
DevicePool.devicesCache = { 'cached-id': device };
|
|
51
|
+
|
|
52
|
+
const result = await DevicePool.getDevices([descriptor], 'cached-id', {
|
|
53
|
+
forceProtocolDetection: true,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(acquire).toHaveBeenCalledWith(undefined, { forceProtocolDetection: true });
|
|
57
|
+
expect(initialize).toHaveBeenCalledWith({ forceProtocolDetection: true });
|
|
58
|
+
expect(release).toHaveBeenCalledTimes(1);
|
|
59
|
+
expect(device.originalDescriptor.protocolType).toBe('V2');
|
|
60
|
+
expect(result.deviceList).toEqual([device]);
|
|
61
|
+
});
|
|
62
|
+
|
|
41
63
|
test('keeps a discovered device when its Protocol V2 label cannot be read', async () => {
|
|
42
64
|
const labelError = new Error('settings unavailable');
|
|
43
65
|
const getDeviceState = jest
|