@onekeyfe/hd-core 1.2.0-alpha.66 → 1.2.0-alpha.67
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 +0 -313
- package/__tests__/DeviceCommands.test.ts +13 -59
- package/__tests__/DeviceEventRegistration.test.ts +0 -6
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +3 -198
- package/__tests__/connectSettings.test.ts +47 -5
- package/__tests__/device-initialize-timeout.test.ts +56 -0
- package/__tests__/device-lifecycle-events.test.ts +3 -105
- package/__tests__/device-pool-state.test.ts +0 -22
- package/__tests__/device-settings.test.ts +18 -39
- package/__tests__/device-state-contract.test.ts +0 -1
- package/__tests__/device-state-mapper.test.ts +1 -13
- package/__tests__/device-utils.test.ts +1 -48
- package/__tests__/deviceSettings.test.ts +1 -11
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
- package/__tests__/firmware-update/device-update-bootloader.test.ts +87 -0
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +119 -0
- package/__tests__/firmware-update/firmware-host-binding.test.ts +70 -0
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +200 -0
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +394 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +593 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +231 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +59 -31
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +58 -0
- package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
- package/__tests__/get-device-state.test.ts +12 -132
- package/__tests__/homescreen.test.ts +1 -41
- package/__tests__/kaspa-use-tweak-pro2.test.ts +2 -2
- package/__tests__/kaspaSignTransaction.test.ts +26 -3
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +0 -19
- package/__tests__/open-wallet-session.test.ts +37 -568
- package/__tests__/protocol-v2-unlock-policy.test.ts +37 -300
- package/__tests__/protocol-v2.test.ts +1153 -1458
- package/__tests__/protocolV2FileWrite.test.ts +0 -152
- package/__tests__/protocolV2UiInteraction.test.ts +0 -63
- package/__tests__/public-pro2-api-boundary.test.ts +0 -1
- package/__tests__/search-devices.test.ts +3 -12
- package/__tests__/tron-sign-message-init.test.ts +2 -2
- package/dist/api/BaseMethod.d.ts +1 -3
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +1 -2
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +10 -0
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +7 -3
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +27 -13
- 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 +5 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +25 -0
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts +6 -0
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +1 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts +3 -0
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +11 -4
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +3 -0
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +25 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +32 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/api/firmware/getBinary.d.ts +7 -0
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/progressThrottle.d.ts +3 -0
- package/dist/api/firmware/progressThrottle.d.ts.map +1 -0
- package/dist/api/firmware/updateBootloader.d.ts +2 -0
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +9 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +0 -9
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +0 -2
- 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/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 +0 -2
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +4 -9
- 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 +6 -29
- 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 +1 -2
- 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 +0 -4
- 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 +2 -4
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +2 -31
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +2 -10
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +247 -243
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3773 -3054
- package/dist/inject.d.ts +1 -6
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts +4 -0
- 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/lockedError.d.ts +2 -0
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +4 -7
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +3 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +10 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +1 -6
- 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 +5 -3
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +1 -5
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +6 -0
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +4 -2
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +70 -4
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +9 -0
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts +28 -0
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +1 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +42 -0
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +10 -7
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +0 -3
- 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 +0 -1
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +21 -38
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +1 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +0 -4
- 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 +0 -4
- 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/pro2Wallpaper.d.ts +0 -10
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +10 -8
- package/src/api/CheckAllFirmwareRelease.ts +60 -59
- package/src/api/FirmwareUpdate.ts +15 -7
- package/src/api/FirmwareUpdateV2.ts +298 -126
- package/src/api/FirmwareUpdateV3.ts +265 -63
- package/src/api/FirmwareUpdateV4.ts +1017 -602
- package/src/api/GetPassphraseState.ts +1 -7
- package/src/api/OpenWalletSession.ts +17 -71
- package/src/api/SearchDevices.ts +1 -3
- package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +11 -36
- package/src/api/device/DeviceSettings.ts +4 -5
- package/src/api/device/DeviceUnlock.ts +3 -8
- package/src/api/device/DeviceUpdateBootloader.ts +125 -6
- package/src/api/firmware/FirmwareArtifactSource.ts +278 -0
- package/src/api/firmware/FirmwareHostBinding.ts +100 -0
- package/src/api/firmware/FirmwarePreparationError.ts +12 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +83 -27
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +772 -0
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +449 -0
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/firmware/updateBootloader.ts +19 -4
- package/src/api/firmware/uploadFirmware.ts +144 -39
- package/src/api/helpers/protocolV2FileWrite.ts +63 -202
- package/src/api/index.ts +0 -2
- package/src/api/kaspa/KaspaGetAddress.ts +1 -1
- package/src/api/kaspa/KaspaSignTransaction.ts +13 -2
- package/src/api/polkadot/networks.ts +3 -3
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +1 -3
- 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 +0 -4
- package/src/core/index.ts +111 -213
- package/src/data/messages/messages-protocol-v2.json +0 -25
- package/src/data-manager/DataManager.ts +41 -113
- package/src/data-manager/TransportManager.ts +0 -6
- package/src/data-manager/connectSettings.ts +11 -0
- package/src/device/Device.ts +49 -274
- package/src/device/DeviceCommands.ts +4 -31
- package/src/device/DeviceConnector.ts +13 -33
- package/src/device/DevicePool.ts +7 -21
- package/src/deviceProfile/buildDeviceFeatures.ts +2 -2
- package/src/deviceProfile/protocolV2DeviceIdentity.ts +0 -3
- package/src/events/device.ts +0 -4
- package/src/events/logBlockEvent.ts +0 -1
- package/src/events/ui-promise.ts +2 -4
- package/src/events/ui-request.ts +2 -36
- package/src/events/ui-response.ts +2 -12
- package/src/index.ts +5 -0
- package/src/inject.ts +24 -60
- package/src/lowLevelInject.ts +8 -7
- package/src/protocols/protocol-v2/features.ts +7 -10
- package/src/protocols/protocol-v2/firmware.ts +0 -2
- package/src/protocols/protocol-v2/lockedError.ts +10 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +6 -46
- package/src/protocols/protocol-v2/unlockPolicy.ts +105 -1
- package/src/protocols/protocol-v2/unlockRetry.ts +109 -0
- package/src/protocols/protocol-v2/walletSession.ts +36 -214
- package/src/topLevelInject.ts +8 -7
- package/src/types/api/checkAllFirmwareRelease.ts +5 -3
- package/src/types/api/deviceUnlock.ts +1 -12
- package/src/types/api/deviceUpdateBootloader.ts +6 -0
- package/src/types/api/export.ts +18 -1
- package/src/types/api/firmwareUpdate.ts +78 -6
- package/src/types/api/firmwareUpdateCapabilities.ts +9 -0
- package/src/types/api/firmwareUpdatePlan.ts +38 -0
- package/src/types/api/firmwareUpdatePreparedPlan.ts +53 -0
- package/src/types/api/index.ts +14 -13
- package/src/types/api/protocolV2.ts +0 -13
- package/src/types/device.ts +3 -15
- package/src/types/params.ts +1 -7
- package/src/types/settings.ts +22 -60
- package/src/utils/deviceFeaturesCompat.ts +6 -5
- package/src/utils/deviceFeaturesUtils.ts +3 -14
- package/src/utils/deviceInfoUtils.ts +0 -2
- package/src/utils/deviceSettings.ts +0 -3
- package/src/utils/homescreen.ts +6 -32
- package/src/utils/index.ts +1 -6
- package/src/utils/pro2Wallpaper.ts +8 -35
- package/__tests__/core-initialization.test.ts +0 -23
- package/__tests__/device-connector-protocol.test.ts +0 -81
- package/__tests__/deviceUploadNft.test.ts +0 -316
- package/__tests__/pro2Nft.test.ts +0 -108
- package/__tests__/protocol-binding.test.ts +0 -89
- package/__tests__/protocol-v2-resources.test.ts +0 -340
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +0 -91
- package/__tests__/uiProgressThrottle.test.ts +0 -74
- package/__tests__/uiPromiseRegistry.test.ts +0 -115
- package/dist/api/DetectDeviceConnectProtocol.d.ts +0 -7
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +0 -31
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +0 -1
- package/dist/core/uiPromiseRegistry.d.ts +0 -6
- package/dist/core/uiPromiseRegistry.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/resources.d.ts +0 -30
- package/dist/protocols/protocol-v2/resources.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +0 -22
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +0 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +0 -4
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +0 -1
- package/dist/utils/pro2Nft.d.ts +0 -31
- package/dist/utils/pro2Nft.d.ts.map +0 -1
- package/dist/utils/uiProgressThrottle.d.ts +0 -3
- package/dist/utils/uiProgressThrottle.d.ts.map +0 -1
- package/src/api/DetectDeviceConnectProtocol.ts +0 -18
- package/src/api/protocol-v2/DeviceUploadNft.ts +0 -197
- package/src/core/uiPromiseRegistry.ts +0 -63
- package/src/protocols/protocol-v2/resources.ts +0 -390
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +0 -131
- package/src/types/api/detectDeviceConnectProtocol.ts +0 -6
- package/src/utils/pro2Nft.ts +0 -142
- package/src/utils/uiProgressThrottle.ts +0 -63
|
@@ -5,7 +5,6 @@ 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';
|
|
9
8
|
|
|
10
9
|
import type { CoreApi } from '../src/types/api';
|
|
11
10
|
import type { DeviceStateVersions, IFirmwareReleaseInfo } from '../src/types';
|
|
@@ -73,74 +72,7 @@ const release: IFirmwareReleaseInfo = {
|
|
|
73
72
|
],
|
|
74
73
|
};
|
|
75
74
|
|
|
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
|
-
|
|
139
75
|
describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
140
|
-
afterEach(() => {
|
|
141
|
-
jest.restoreAllMocks();
|
|
142
|
-
});
|
|
143
|
-
|
|
144
76
|
test('builds ordered firmwareUpdateV4 targets from recommended component versions', () => {
|
|
145
77
|
const result = buildProtocolV2FirmwareRelease({
|
|
146
78
|
currentVersions,
|
|
@@ -152,7 +84,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
152
84
|
status: 'required',
|
|
153
85
|
hasUpgrade: true,
|
|
154
86
|
required: true,
|
|
155
|
-
targetsToUpdate: ['boot', 'app_v1'],
|
|
87
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
156
88
|
components: [
|
|
157
89
|
{ configKey: 'bootloader', status: 'outdated', updateTarget: 'boot' },
|
|
158
90
|
{ configKey: 'applicationP1', status: 'outdated', updateTarget: 'app_v1' },
|
|
@@ -210,7 +142,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
210
142
|
applicationP1Hash: 'aa'.repeat(32),
|
|
211
143
|
applicationP2Hash: 'bb'.repeat(32),
|
|
212
144
|
},
|
|
213
|
-
checkFirmwareHash: true,
|
|
214
145
|
remotePayloadHashes: {
|
|
215
146
|
applicationP1: 'aa'.repeat(64),
|
|
216
147
|
applicationP2: 'cc'.repeat(64),
|
|
@@ -229,37 +160,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
229
160
|
});
|
|
230
161
|
});
|
|
231
162
|
|
|
232
|
-
test('uses version-only comparison for same-version packages by default', () => {
|
|
233
|
-
const packageSet: IFirmwareReleaseInfo = {
|
|
234
|
-
...release,
|
|
235
|
-
required: false,
|
|
236
|
-
resourceBundles: undefined,
|
|
237
|
-
installOrder: ['applicationP1'],
|
|
238
|
-
components: {
|
|
239
|
-
applicationP1: {
|
|
240
|
-
target: 'APPLICATION_P1',
|
|
241
|
-
version: [1, 0, 0],
|
|
242
|
-
url: 'https://example.com/application-p1.okpkg',
|
|
243
|
-
payloadHash: 'cc'.repeat(64),
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
expect(
|
|
249
|
-
buildProtocolV2FirmwareRelease({
|
|
250
|
-
currentVersions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
251
|
-
currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
252
|
-
firmwareType: EFirmwareType.Universal,
|
|
253
|
-
release: packageSet,
|
|
254
|
-
})
|
|
255
|
-
).toMatchObject({
|
|
256
|
-
status: 'valid',
|
|
257
|
-
hasUpgrade: false,
|
|
258
|
-
targetsToUpdate: [],
|
|
259
|
-
components: [{ configKey: 'applicationP1', status: 'valid' }],
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
|
|
263
163
|
test('keeps same-version hash-aware components unknown without metadata payloadHash', () => {
|
|
264
164
|
const packageSet: IFirmwareReleaseInfo = {
|
|
265
165
|
...release,
|
|
@@ -280,7 +180,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
280
180
|
buildProtocolV2FirmwareRelease({
|
|
281
181
|
currentVersions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
282
182
|
currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
283
|
-
checkFirmwareHash: true,
|
|
284
183
|
firmwareType: EFirmwareType.Universal,
|
|
285
184
|
release: packageSet,
|
|
286
185
|
})
|
|
@@ -316,7 +215,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
316
215
|
const result = buildProtocolV2FirmwareRelease({
|
|
317
216
|
currentVersions,
|
|
318
217
|
currentVerification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
319
|
-
checkFirmwareHash: true,
|
|
320
218
|
remotePayloadHashes: { applicationP1: 'cc'.repeat(64) },
|
|
321
219
|
firmwareType: EFirmwareType.Universal,
|
|
322
220
|
release: packageSet,
|
|
@@ -325,7 +223,7 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
325
223
|
expect(result.targetsToUpdate).toEqual(['app_v1', 'app_v2']);
|
|
326
224
|
});
|
|
327
225
|
|
|
328
|
-
test('
|
|
226
|
+
test('uses the existing method on Protocol V2 and keeps its public API name', async () => {
|
|
329
227
|
const method = new CheckAllFirmwareRelease({
|
|
330
228
|
id: 1,
|
|
331
229
|
payload: {
|
|
@@ -342,7 +240,6 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
342
240
|
status: { mode: 'normal' },
|
|
343
241
|
versions: currentVersions,
|
|
344
242
|
});
|
|
345
|
-
const typedCall = createFilesystemTypedCall(true);
|
|
346
243
|
method.device = {
|
|
347
244
|
isProtocolV2: () => true,
|
|
348
245
|
features: {
|
|
@@ -350,124 +247,32 @@ describe('checkAllFirmwareRelease Protocol V2 support', () => {
|
|
|
350
247
|
firmwareVersion: '1.0.0',
|
|
351
248
|
},
|
|
352
249
|
getDeviceState,
|
|
353
|
-
getCommands: () => ({ typedCall }),
|
|
354
250
|
} as unknown as CheckAllFirmwareRelease['device'];
|
|
355
251
|
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
356
|
-
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
|
|
357
252
|
|
|
358
253
|
await expect(method.run()).resolves.toMatchObject({
|
|
359
254
|
protocol: 'V2',
|
|
360
255
|
deviceType: 'pro2',
|
|
361
256
|
status: 'required',
|
|
362
|
-
|
|
363
|
-
targetsToUpdate: ['boot', 'app_v1'],
|
|
257
|
+
targetsToUpdate: ['boot', 'app_v1', 'resource'],
|
|
364
258
|
firmware: {
|
|
365
259
|
status: 'required',
|
|
366
260
|
},
|
|
367
261
|
});
|
|
368
|
-
expect(typedCall).not.toHaveBeenCalled();
|
|
369
|
-
expect(getDeviceState).toHaveBeenCalledWith({
|
|
370
|
-
refreshSections: ['identity', 'versions'],
|
|
371
|
-
});
|
|
372
262
|
expect(method.getSupportedProtocols()).toEqual(['V1', 'V2']);
|
|
373
263
|
});
|
|
374
264
|
|
|
375
|
-
test('requests and compares firmware hashes only when explicitly enabled', async () => {
|
|
376
|
-
const packageSet: IFirmwareReleaseInfo = {
|
|
377
|
-
...release,
|
|
378
|
-
required: false,
|
|
379
|
-
resourceBundles: undefined,
|
|
380
|
-
installOrder: ['applicationP1'],
|
|
381
|
-
components: {
|
|
382
|
-
applicationP1: {
|
|
383
|
-
target: 'APPLICATION_P1',
|
|
384
|
-
version: [1, 0, 0],
|
|
385
|
-
url: 'https://example.com/application-p1.okpkg',
|
|
386
|
-
payloadHash: 'cc'.repeat(64),
|
|
387
|
-
},
|
|
388
|
-
},
|
|
389
|
-
};
|
|
390
|
-
const method = new CheckAllFirmwareRelease({
|
|
391
|
-
id: 1,
|
|
392
|
-
payload: {
|
|
393
|
-
method: 'checkAllFirmwareRelease',
|
|
394
|
-
firmwareType: EFirmwareType.Universal,
|
|
395
|
-
checkFirmwareHash: true,
|
|
396
|
-
},
|
|
397
|
-
});
|
|
398
|
-
method.init();
|
|
399
|
-
const getDeviceState = jest.fn().mockResolvedValue({
|
|
400
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
401
|
-
status: { mode: 'normal' },
|
|
402
|
-
versions: { ...currentVersions, applicationP1: '1.0.0' },
|
|
403
|
-
verification: { applicationP1Hash: 'aa'.repeat(32) },
|
|
404
|
-
});
|
|
405
|
-
method.device = {
|
|
406
|
-
isProtocolV2: () => true,
|
|
407
|
-
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
408
|
-
getDeviceState,
|
|
409
|
-
getCommands: () => ({ typedCall: jest.fn() }),
|
|
410
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
411
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(packageSet);
|
|
412
|
-
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(undefined);
|
|
413
|
-
|
|
414
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
415
|
-
status: 'outdated',
|
|
416
|
-
targetsToUpdate: ['app_v1'],
|
|
417
|
-
});
|
|
418
|
-
expect(getDeviceState).toHaveBeenCalledWith({
|
|
419
|
-
refreshSections: ['identity', 'versions', 'verification'],
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
test.each(['bootloader', 'romloader'] as const)(
|
|
424
|
-
'uses filesystem inventory in %s mode instead of forcing all resources',
|
|
425
|
-
async mode => {
|
|
426
|
-
const method = new CheckAllFirmwareRelease({
|
|
427
|
-
id: 1,
|
|
428
|
-
payload: {
|
|
429
|
-
method: 'checkAllFirmwareRelease',
|
|
430
|
-
firmwareType: EFirmwareType.Universal,
|
|
431
|
-
},
|
|
432
|
-
});
|
|
433
|
-
method.init();
|
|
434
|
-
const typedCall = createFilesystemTypedCall();
|
|
435
|
-
method.device = {
|
|
436
|
-
isProtocolV2: () => true,
|
|
437
|
-
features: { deviceType: 'pro2', firmwareVersion: '1.0.0' },
|
|
438
|
-
getDeviceState: jest.fn().mockResolvedValue({
|
|
439
|
-
identity: { deviceType: 'pro2', firmwareType: EFirmwareType.Universal },
|
|
440
|
-
status: { mode },
|
|
441
|
-
versions: currentVersions,
|
|
442
|
-
}),
|
|
443
|
-
getCommands: () => ({ typedCall }),
|
|
444
|
-
} as unknown as CheckAllFirmwareRelease['device'];
|
|
445
|
-
jest.spyOn(DataManager, 'getFirmwareLatestRelease').mockReturnValue(release);
|
|
446
|
-
jest.spyOn(DataManager, 'getProtocolV2Resources').mockReturnValue(stableResources as any);
|
|
447
|
-
|
|
448
|
-
await expect(method.run()).resolves.toMatchObject({
|
|
449
|
-
protocol: 'V2',
|
|
450
|
-
resourceStatus: 'valid',
|
|
451
|
-
targetsToUpdate: ['boot', 'app_v1'],
|
|
452
|
-
});
|
|
453
|
-
expect(typedCall.mock.calls.some(call => call[0] === 'ResourceInventoryGet')).toBe(false);
|
|
454
|
-
expect(typedCall.mock.calls.some(call => call[0] === 'FilesystemFileRead')).toBe(true);
|
|
455
|
-
}
|
|
456
|
-
);
|
|
457
|
-
|
|
458
265
|
test('continues forwarding the existing public method', async () => {
|
|
459
266
|
const call = jest.fn().mockResolvedValue({ success: true, payload: {} });
|
|
460
267
|
const api = createCoreApi(call as CoreApi['call']) as CoreApi;
|
|
461
268
|
|
|
462
269
|
await api.checkAllFirmwareRelease('pro2-connect-id', {
|
|
463
|
-
checkFirmwareHash: true,
|
|
464
270
|
firmwareType: EFirmwareType.Universal,
|
|
465
271
|
retryCount: 0,
|
|
466
272
|
});
|
|
467
273
|
|
|
468
274
|
expect(call).toHaveBeenCalledWith({
|
|
469
275
|
connectId: 'pro2-connect-id',
|
|
470
|
-
checkFirmwareHash: true,
|
|
471
276
|
firmwareType: EFirmwareType.Universal,
|
|
472
277
|
retryCount: 0,
|
|
473
278
|
method: 'checkAllFirmwareRelease',
|
|
@@ -1,19 +1,61 @@
|
|
|
1
|
+
import DataManager from '../src/data-manager/DataManager';
|
|
1
2
|
import { parseConnectSettings } from '../src/data-manager/connectSettings';
|
|
2
3
|
|
|
4
|
+
import type { RemoteConfigResponse } from '../src/types';
|
|
5
|
+
|
|
6
|
+
jest.mock('axios', () => ({
|
|
7
|
+
get: jest.fn(),
|
|
8
|
+
}));
|
|
9
|
+
|
|
3
10
|
jest.mock('../src/data/config', () => ({
|
|
4
11
|
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
5
12
|
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
6
13
|
}));
|
|
7
14
|
|
|
15
|
+
const mockAxiosGet: jest.Mock = jest.requireMock('axios').get;
|
|
16
|
+
|
|
8
17
|
describe('parseConnectSettings', () => {
|
|
9
|
-
|
|
10
|
-
|
|
18
|
+
const preloadedConfig = {
|
|
19
|
+
bridge: {},
|
|
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
|
+
});
|
|
11
50
|
|
|
51
|
+
it('fails closed without a preloaded config in external-only mode', async () => {
|
|
12
52
|
const settings = parseConnectSettings({
|
|
13
|
-
|
|
14
|
-
configFetcher,
|
|
53
|
+
firmwareManifestMode: 'external-only',
|
|
15
54
|
});
|
|
16
55
|
|
|
17
|
-
expect(settings
|
|
56
|
+
await expect(DataManager.load(settings)).rejects.toThrow(
|
|
57
|
+
'External firmware config snapshot is required'
|
|
58
|
+
);
|
|
59
|
+
expect(mockAxiosGet).not.toHaveBeenCalled();
|
|
18
60
|
});
|
|
19
61
|
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Device } from '../src/device/Device';
|
|
2
|
+
import TransportManager from '../src/data-manager/TransportManager';
|
|
3
|
+
|
|
4
|
+
jest.mock('../src/data/config', () => ({
|
|
5
|
+
getSDKVersion: jest.fn(() => '1.0.0'),
|
|
6
|
+
DEFAULT_DOMAIN: 'https://jssdk.onekey.so/1.0.0/',
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
function buildV1Device() {
|
|
10
|
+
const device = Object.create(Device.prototype) as Device;
|
|
11
|
+
const typedCall = jest.fn(() => Promise.resolve({ message: { device_id: 'device' } }));
|
|
12
|
+
Object.assign(device, {
|
|
13
|
+
commands: { typedCall },
|
|
14
|
+
stateStore: { getState: () => undefined },
|
|
15
|
+
isProtocolV2: () => false,
|
|
16
|
+
_updateFeatures: jest.fn(),
|
|
17
|
+
getInternalState: jest.fn(() => undefined),
|
|
18
|
+
});
|
|
19
|
+
return { device, typedCall };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('Device.initialize Protocol V1 timeout', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
jest.spyOn(TransportManager, 'reconfigure').mockResolvedValue(undefined);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
jest.restoreAllMocks();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('passes a custom Initialize timeout through to typedCall', async () => {
|
|
32
|
+
const { device, typedCall } = buildV1Device();
|
|
33
|
+
|
|
34
|
+
await device.initialize({ timeoutMs: 2500 });
|
|
35
|
+
|
|
36
|
+
expect(typedCall).toHaveBeenCalledWith(
|
|
37
|
+
'Initialize',
|
|
38
|
+
'Features',
|
|
39
|
+
expect.objectContaining({ is_contains_attach: true }),
|
|
40
|
+
{ timeoutMs: 2500 }
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('keeps the 25s Initialize timeout by default', async () => {
|
|
45
|
+
const { device, typedCall } = buildV1Device();
|
|
46
|
+
|
|
47
|
+
await device.initialize();
|
|
48
|
+
|
|
49
|
+
expect(typedCall).toHaveBeenCalledWith(
|
|
50
|
+
'Initialize',
|
|
51
|
+
'Features',
|
|
52
|
+
expect.objectContaining({ is_contains_attach: true }),
|
|
53
|
+
{ timeoutMs: 25 * 1000 }
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
1
|
import { TRANSPORT_EVENT } from '@onekeyfe/hd-transport';
|
|
3
2
|
|
|
4
3
|
import { initConnector, initCore } from '../src/core';
|
|
@@ -96,25 +95,7 @@ describe('public device lifecycle events', () => {
|
|
|
96
95
|
expect(messages.filter(message => message.type === DEVICE.DISCONNECT)).toHaveLength(1);
|
|
97
96
|
});
|
|
98
97
|
|
|
99
|
-
test('uses a
|
|
100
|
-
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
101
|
-
const device = Device.fromDescriptor({
|
|
102
|
-
id: 'ble-id',
|
|
103
|
-
path: 'ble-id',
|
|
104
|
-
commType: 'ble',
|
|
105
|
-
protocolType: 'V1',
|
|
106
|
-
} as never);
|
|
107
|
-
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V1' });
|
|
108
|
-
device.deviceConnector = { acquire } as never;
|
|
109
|
-
|
|
110
|
-
await device.acquire();
|
|
111
|
-
|
|
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 () => {
|
|
98
|
+
test('uses a cached protocol as a fallback-capable acquire hint', async () => {
|
|
118
99
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
119
100
|
const device = Device.fromDescriptor({
|
|
120
101
|
id: 'ble-id',
|
|
@@ -125,96 +106,13 @@ describe('public device lifecycle events', () => {
|
|
|
125
106
|
const acquire = jest.fn().mockResolvedValue({ uuid: 'ble-id', protocolType: 'V2' });
|
|
126
107
|
device.deviceConnector = { acquire } as never;
|
|
127
108
|
|
|
128
|
-
await device.acquire(
|
|
109
|
+
await device.acquire();
|
|
129
110
|
|
|
130
|
-
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, undefined,
|
|
111
|
+
expect(acquire).toHaveBeenCalledWith('ble-id', undefined, true, undefined, 'V1');
|
|
131
112
|
expect(device.getProtocol()).toBe('V2');
|
|
132
113
|
expect(device.originalDescriptor.protocolType).toBe('V2');
|
|
133
114
|
});
|
|
134
115
|
|
|
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
|
-
|
|
218
116
|
test('keeps an explicit connectProtocol as a strict expected protocol', async () => {
|
|
219
117
|
jest.spyOn(DataManager, 'getSettings').mockReturnValue('react-native' as never);
|
|
220
118
|
const device = Device.fromDescriptor({
|
|
@@ -38,28 +38,6 @@ 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
|
-
|
|
63
41
|
test('keeps a discovered device when its Protocol V2 label cannot be read', async () => {
|
|
64
42
|
const labelError = new Error('settings unavailable');
|
|
65
43
|
const getDeviceState = jest
|
|
@@ -115,8 +115,8 @@ describe('DeviceSettings protocol routing', () => {
|
|
|
115
115
|
);
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
it('uses DeviceSettingsSet and
|
|
119
|
-
const { device, typedCall, updateState
|
|
118
|
+
it('uses DeviceSettingsSet and commits the confirmed patch for Protocol V2', async () => {
|
|
119
|
+
const { device, typedCall, updateState } = createDevice({ protocol: 'V2' });
|
|
120
120
|
const method = new DeviceSettings({
|
|
121
121
|
id: 2,
|
|
122
122
|
payload: {
|
|
@@ -141,10 +141,21 @@ describe('DeviceSettings protocol routing', () => {
|
|
|
141
141
|
haptic_feedback: true,
|
|
142
142
|
},
|
|
143
143
|
});
|
|
144
|
-
expect(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
144
|
+
expect(updateState).toHaveBeenCalledWith(
|
|
145
|
+
{
|
|
146
|
+
identity: { label: 'Shared Label' },
|
|
147
|
+
settings: {
|
|
148
|
+
language: 'ja',
|
|
149
|
+
bleEnabled: true,
|
|
150
|
+
autoLockDelayMs: 60_000,
|
|
151
|
+
hapticFeedback: true,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
'settings-write'
|
|
155
|
+
);
|
|
156
|
+
expect(typedCall.mock.calls.map(call => call[0])).not.toEqual(
|
|
157
|
+
expect.arrayContaining(['DeviceInfoGet', 'DeviceStatusGet', 'DeviceSettingsGet'])
|
|
158
|
+
);
|
|
148
159
|
});
|
|
149
160
|
|
|
150
161
|
it('uses the Pro2 passphrase page as a device-side toggle and verifies the target state', async () => {
|
|
@@ -172,39 +183,7 @@ describe('DeviceSettings protocol routing', () => {
|
|
|
172
183
|
});
|
|
173
184
|
expect(typedCall).not.toHaveBeenCalledWith('DeviceSettingsSet', 'Success', expect.anything());
|
|
174
185
|
expect(getDeviceState).toHaveBeenNthCalledWith(1, { refreshSections: ['status'] });
|
|
175
|
-
expect(getDeviceState).toHaveBeenNthCalledWith(2, {
|
|
176
|
-
refreshSections: ['status', 'settings'],
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('reloads Protocol V2 status and settings after changing air-gap mode', async () => {
|
|
181
|
-
const { device, typedCall, getDeviceState } = createDevice({ protocol: 'V2' });
|
|
182
|
-
getDeviceState
|
|
183
|
-
.mockResolvedValueOnce({
|
|
184
|
-
settings: { airgapMode: false },
|
|
185
|
-
})
|
|
186
|
-
.mockResolvedValueOnce({
|
|
187
|
-
status: { unlocked: true },
|
|
188
|
-
settings: { airgapMode: true },
|
|
189
|
-
});
|
|
190
|
-
const method = new DeviceSettings({
|
|
191
|
-
id: 4,
|
|
192
|
-
payload: {
|
|
193
|
-
method: 'deviceSettings',
|
|
194
|
-
airgapMode: true,
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
method.init();
|
|
198
|
-
(method as any).device = device;
|
|
199
|
-
|
|
200
|
-
await expect(method.run()).resolves.toEqual({ message: 'Success' });
|
|
201
|
-
expect(typedCall).toHaveBeenCalledWith('DeviceSettingsPageShow', 'Success', {
|
|
202
|
-
page: DeviceSettingsPage.DeviceAirgap,
|
|
203
|
-
});
|
|
204
|
-
expect(getDeviceState).toHaveBeenNthCalledWith(1, { refreshSections: ['settings'] });
|
|
205
|
-
expect(getDeviceState).toHaveBeenNthCalledWith(2, {
|
|
206
|
-
refreshSections: ['status', 'settings'],
|
|
207
|
-
});
|
|
186
|
+
expect(getDeviceState).toHaveBeenNthCalledWith(2, { refreshSections: ['status'] });
|
|
208
187
|
});
|
|
209
188
|
|
|
210
189
|
it('does not open a Pro2 settings page when the hardware already matches the target', async () => {
|