@onekeyfe/hd-core 1.2.0-alpha.2 → 1.2.0-alpha.21
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 +75 -0
- package/__tests__/DeviceCommands.test.ts +285 -0
- package/__tests__/DeviceEventRegistration.test.ts +43 -0
- package/__tests__/connectSettings.test.ts +19 -0
- package/__tests__/core-dispose.test.ts +34 -0
- package/__tests__/core-error-output.test.ts +39 -0
- package/__tests__/device-features-state.test.ts +78 -0
- package/__tests__/device-identity.test.ts +30 -0
- package/__tests__/device-lifecycle-events.test.ts +117 -0
- package/__tests__/device-pool-state.test.ts +132 -0
- package/__tests__/device-settings.test.ts +391 -0
- package/__tests__/device-state-contract.test.ts +27 -0
- package/__tests__/device-state-events.test.ts +162 -0
- package/__tests__/device-state-mapper.test.ts +241 -0
- package/__tests__/device-state-projector.test.ts +94 -0
- package/__tests__/device-state-store.test.ts +82 -0
- package/__tests__/device-utils.test.ts +106 -0
- package/__tests__/device-wallet-session-store.test.ts +213 -0
- package/__tests__/deviceFeaturesUtils.test.ts +39 -0
- package/__tests__/deviceSettings.test.ts +103 -0
- package/__tests__/evmLedgerLegacySafety.test.ts +10 -6
- package/__tests__/evmSignTypedData.test.ts +80 -0
- package/__tests__/filesystemValidation.test.ts +53 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +402 -0
- package/__tests__/get-device-state.test.ts +410 -0
- package/__tests__/homescreen.test.ts +24 -0
- package/__tests__/kaspaSignTransaction.test.ts +591 -0
- package/__tests__/logBlockEvent.test.ts +26 -0
- package/__tests__/networkUtils.test.ts +386 -0
- package/__tests__/open-wallet-session-error-response.test.ts +43 -0
- package/__tests__/open-wallet-session.test.ts +559 -0
- package/__tests__/preInitialize.test.ts +33 -0
- package/__tests__/pro2Wallpaper.test.ts +50 -0
- package/__tests__/protocol-v2-bootloader-mode.test.ts +37 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +19 -0
- package/__tests__/protocol-v2.test.ts +3954 -1191
- package/__tests__/protocolV2FileWrite.test.ts +92 -0
- package/__tests__/protocolV2UiInteraction.test.ts +266 -0
- package/__tests__/public-device-state-api.test.ts +257 -0
- package/__tests__/public-pro2-api-boundary.test.ts +110 -0
- package/__tests__/refresh-device-state.test.ts +101 -0
- package/__tests__/request-context-logging.test.ts +16 -0
- package/__tests__/search-devices.test.ts +136 -0
- package/dist/api/BaseMethod.d.ts +8 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/ClearSessionCache.d.ts +9 -0
- package/dist/api/ClearSessionCache.d.ts.map +1 -0
- package/dist/api/DirList.d.ts.map +1 -1
- package/dist/api/FileRead.d.ts.map +1 -1
- package/dist/api/FileWrite.d.ts +1 -0
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +2 -2
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +25 -5
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetDeviceState.d.ts +7 -0
- package/dist/api/GetDeviceState.d.ts.map +1 -0
- package/dist/api/GetFeatures.d.ts +1 -1
- package/dist/api/GetFeatures.d.ts.map +1 -1
- package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts +1 -6
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts +14 -0
- package/dist/api/OpenWalletSession.d.ts.map +1 -0
- package/dist/api/PathInfo.d.ts.map +1 -1
- package/dist/api/PromptWebDeviceAccess.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts +3 -0
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +17 -0
- package/dist/api/UploadPortfolio.d.ts.map +1 -0
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceCancel.d.ts.map +1 -1
- package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
- package/dist/api/device/DeviceFullyUploadResource.d.ts +1 -2
- package/dist/api/device/DeviceFullyUploadResource.d.ts.map +1 -1
- package/dist/api/device/DeviceLock.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceSettings.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +1 -1
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceWipe.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +11 -3
- 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/helpers/filesystemValidation.d.ts +3 -0
- package/dist/api/helpers/filesystemValidation.d.ts.map +1 -1
- package/dist/api/helpers/paramsValidator.d.ts +1 -0
- package/dist/api/helpers/paramsValidator.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +33 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -0
- package/dist/api/index.d.ts +12 -19
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts +5 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
- package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +3 -2
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts +28 -0
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +26 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
- package/dist/api/protocol-v2/{FilesystemFixPermission.d.ts → FilesystemPermissionFix.d.ts} +2 -2
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +6 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -0
- package/dist/api/protocol-v2/helpers.d.ts +27 -19
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/ton/TonSignData.d.ts +1 -5
- package/dist/api/ton/TonSignData.d.ts.map +1 -1
- package/dist/api/utils.d.ts +2 -1
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/constants/index.d.ts +2 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/deviceEventRegistration.d.ts +11 -0
- package/dist/core/deviceEventRegistration.d.ts.map +1 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +1 -1
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +35 -11
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +8 -6
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceFeaturesState.d.ts +3 -0
- package/dist/device/DeviceFeaturesState.d.ts.map +1 -0
- package/dist/device/DevicePool.d.ts +4 -2
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/device/DeviceStateMapper.d.ts +13 -0
- package/dist/device/DeviceStateMapper.d.ts.map +1 -0
- package/dist/device/DeviceStateProjector.d.ts +7 -0
- package/dist/device/DeviceStateProjector.d.ts.map +1 -0
- package/dist/device/DeviceStateStore.d.ts +21 -0
- package/dist/device/DeviceStateStore.d.ts.map +1 -0
- package/dist/device/DeviceWalletSessionStore.d.ts +20 -0
- package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
- package/dist/device/cloneDeviceState.d.ts +2 -0
- package/dist/device/cloneDeviceState.d.ts.map +1 -0
- package/dist/device/deviceIdentity.d.ts +5 -0
- package/dist/device/deviceIdentity.d.ts.map +1 -0
- package/dist/deviceProfile/buildDeviceFeatures.d.ts +9 -3
- package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
- package/dist/deviceProfile/index.d.ts +0 -1
- package/dist/deviceProfile/index.d.ts.map +1 -1
- package/dist/events/device.d.ts +11 -2
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +18 -2
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +1361 -609
- package/dist/index.js +5898 -2860
- package/dist/inject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/deviceSession.d.ts +7 -0
- package/dist/protocols/protocol-v2/deviceSession.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/features.d.ts +23 -28
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.d.ts +11 -9
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/index.d.ts +3 -2
- package/dist/protocols/protocol-v2/index.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/settingsUnlockPolicy.d.ts +16 -0
- package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +39 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +11 -0
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +19 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
- package/dist/types/api/checkAllFirmwareRelease.d.ts +1 -2
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceSettings.d.ts +11 -2
- package/dist/types/api/deviceSettings.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +2 -2
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +6 -6
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/getDeviceState.d.ts +12 -0
- package/dist/types/api/getDeviceState.d.ts.map +1 -0
- package/dist/types/api/getFeatures.d.ts.map +1 -1
- package/dist/types/api/getOnekeyFeatures.d.ts.map +1 -1
- package/dist/types/api/getPassphraseState.d.ts +2 -10
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +22 -25
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/kaspaSignTransaction.d.ts +27 -2
- package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
- package/dist/types/api/openWalletSession.d.ts +41 -0
- package/dist/types/api/openWalletSession.d.ts.map +1 -0
- package/dist/types/api/protocolV2.d.ts +23 -28
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/sessionCache.d.ts +10 -0
- package/dist/types/api/sessionCache.d.ts.map +1 -0
- package/dist/types/device.d.ts +121 -5
- 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 +21 -1
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/assets.d.ts +2 -1
- package/dist/utils/assets.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +13 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -0
- package/dist/utils/deviceFeaturesUtils.d.ts +13 -3
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts +9 -8
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/deviceSettings.d.ts +38 -7
- package/dist/utils/deviceSettings.d.ts.map +1 -1
- package/dist/utils/deviceVersionUtils.d.ts +6 -5
- package/dist/utils/deviceVersionUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +5 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/networkUtils.d.ts +9 -1
- package/dist/utils/networkUtils.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 +12 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
- package/dist/utils/tracing.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +36 -9
- package/src/api/CheckBootloaderRelease.ts +1 -2
- package/src/api/CheckFirmwareRelease.ts +1 -2
- package/src/api/ClearSessionCache.ts +28 -0
- package/src/api/DirList.ts +5 -3
- package/src/api/DirMake.ts +3 -3
- package/src/api/DirRemove.ts +3 -3
- package/src/api/FileDelete.ts +3 -3
- package/src/api/FileRead.ts +23 -7
- package/src/api/FileWrite.ts +23 -168
- package/src/api/FirmwareUpdate.ts +4 -4
- package/src/api/FirmwareUpdateV2.ts +133 -45
- package/src/api/FirmwareUpdateV3.ts +3 -5
- package/src/api/FirmwareUpdateV4.ts +1138 -357
- package/src/api/GetDeviceState.ts +55 -0
- package/src/api/GetFeatures.ts +8 -3
- package/src/api/GetOnekeyFeatures.ts +3 -72
- package/src/api/GetPassphraseState.ts +11 -18
- package/src/api/OpenWalletSession.ts +221 -0
- package/src/api/PathInfo.ts +5 -3
- package/src/api/PromptWebDeviceAccess.ts +2 -3
- package/src/api/SearchDevices.ts +29 -4
- package/src/api/UploadPortfolio.ts +40 -0
- package/src/api/alephium/AlephiumSignTransaction.ts +2 -2
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +4 -8
- package/src/api/benfen/BenfenGetAddress.ts +1 -1
- package/src/api/btc/BTCGetPublicKey.ts +1 -1
- package/src/api/cardano/CardanoSignMessage.ts +1 -1
- package/src/api/cardano/CardanoSignTransaction.ts +1 -1
- package/src/api/device/DeviceCancel.ts +1 -0
- package/src/api/device/DeviceChangePin.ts +24 -0
- package/src/api/device/DeviceFullyUploadResource.ts +4 -5
- package/src/api/device/DeviceLock.ts +1 -0
- package/src/api/device/DeviceRebootToBoardloader.ts +5 -4
- package/src/api/device/DeviceRebootToBootloader.ts +5 -4
- package/src/api/device/DeviceSettings.ts +183 -1
- package/src/api/device/DeviceUnlock.ts +11 -1
- package/src/api/device/DeviceUpdateBootloader.ts +1 -2
- package/src/api/device/DeviceWipe.ts +19 -0
- package/src/api/evm/EVMSignTypedData.ts +3 -5
- package/src/api/evm/legacyV1/getAddress.ts +2 -2
- package/src/api/evm/legacyV1/getPublicKey.ts +2 -2
- package/src/api/evm/legacyV1/signMessage.ts +2 -2
- package/src/api/evm/legacyV1/signTypedData.ts +2 -2
- package/src/api/evm/legacyV1/signTypedHash.ts +2 -2
- package/src/api/evm/legacyV1/verifyMessage.ts +2 -2
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +21 -7
- package/src/api/firmware/getBinary.ts +8 -3
- package/src/api/firmware/progressThrottle.ts +44 -0
- package/src/api/helpers/batchGetPublickeys.ts +2 -2
- package/src/api/helpers/filesystemValidation.ts +61 -0
- package/src/api/helpers/paramsValidator.ts +1 -1
- package/src/api/helpers/protocolV2FileWrite.ts +193 -0
- package/src/api/index.ts +14 -20
- package/src/api/kaspa/KaspaSignTransaction.ts +341 -22
- package/src/api/kaspa/helpers/TransferSerialize.ts +14 -0
- package/src/api/nervos/NervosSignTransaction.ts +2 -2
- package/src/api/nexa/NexaSignTransaction.ts +1 -1
- package/src/api/protocol-v2/{FactoryGetDeviceInfo.ts → DeviceFactoryInfoGet.ts} +4 -4
- package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +32 -0
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +7 -9
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +41 -6
- package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +6 -4
- package/src/api/protocol-v2/DeviceInfoGet.ts +145 -0
- package/src/api/protocol-v2/DeviceReboot.ts +5 -3
- package/src/api/protocol-v2/DeviceStatusGet.ts +16 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +131 -0
- package/src/api/protocol-v2/FilesystemFormat.ts +5 -2
- package/src/api/protocol-v2/{FilesystemFixPermission.ts → FilesystemPermissionFix.ts} +3 -3
- package/src/api/protocol-v2/Ping.ts +1 -1
- package/src/api/protocol-v2/{GetProtoVersion.ts → ProtocolInfoRequest.ts} +3 -3
- package/src/api/protocol-v2/helpers.ts +58 -62
- package/src/api/ton/TonSignData.ts +1 -5
- package/src/api/utils.ts +7 -3
- package/src/constants/index.ts +7 -1
- package/src/core/RequestQueue.ts +1 -0
- package/src/core/deviceEventRegistration.ts +23 -0
- package/src/core/index.ts +140 -35
- package/src/data/messages/messages-protocol-v2.json +825 -709
- package/src/data/messages/messages.json +286 -1
- package/src/data-manager/DataManager.ts +13 -6
- package/src/data-manager/connectSettings.ts +4 -0
- package/src/device/Device.ts +480 -192
- package/src/device/DeviceCommands.ts +81 -25
- package/src/device/DeviceFeaturesState.ts +25 -0
- package/src/device/DevicePool.ts +67 -19
- package/src/device/DeviceStateMapper.ts +349 -0
- package/src/device/DeviceStateProjector.ts +95 -0
- package/src/device/DeviceStateStore.ts +201 -0
- package/src/device/DeviceWalletSessionStore.ts +105 -0
- package/src/device/cloneDeviceState.ts +39 -0
- package/src/device/deviceIdentity.ts +18 -0
- package/src/deviceProfile/buildDeviceFeatures.ts +235 -210
- package/src/deviceProfile/index.ts +0 -1
- package/src/events/device.ts +17 -1
- package/src/events/logBlockEvent.ts +8 -1
- package/src/events/ui-request.ts +24 -2
- package/src/inject.ts +23 -34
- package/src/protocols/protocol-v2/deviceSession.ts +24 -0
- package/src/protocols/protocol-v2/features.ts +68 -82
- package/src/protocols/protocol-v2/firmware.ts +12 -36
- package/src/protocols/protocol-v2/index.ts +3 -1
- package/src/protocols/protocol-v2/lockedError.ts +10 -0
- package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +61 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +210 -0
- package/src/protocols/protocol-v2/unlockRetry.ts +76 -0
- package/src/protocols/protocol-v2/walletSession.ts +107 -0
- package/src/types/api/checkAllFirmwareRelease.ts +1 -2
- package/src/types/api/deviceSettings.ts +26 -2
- package/src/types/api/deviceUnlock.ts +5 -2
- package/src/types/api/firmwareUpdate.ts +28 -20
- package/src/types/api/getDeviceState.ts +19 -0
- package/src/types/api/getFeatures.ts +3 -0
- package/src/types/api/getOnekeyFeatures.ts +3 -0
- package/src/types/api/getPassphraseState.ts +8 -11
- package/src/types/api/index.ts +30 -53
- package/src/types/api/kaspaSignTransaction.ts +40 -2
- package/src/types/api/openWalletSession.ts +64 -0
- package/src/types/api/protocolV2.ts +58 -55
- package/src/types/api/sessionCache.ts +14 -0
- package/src/types/device.ts +170 -4
- package/src/types/params.ts +4 -0
- package/src/types/settings.ts +42 -30
- package/src/utils/assets.ts +4 -1
- package/src/utils/deviceFeaturesCompat.ts +173 -0
- package/src/utils/deviceFeaturesUtils.ts +68 -24
- package/src/utils/deviceInfoUtils.ts +26 -64
- package/src/utils/deviceSettings.ts +161 -39
- package/src/utils/deviceVersionUtils.ts +25 -44
- package/src/utils/findDefectiveBatchDevice.ts +3 -3
- package/src/utils/homescreen.ts +10 -0
- package/src/utils/index.ts +21 -1
- package/src/utils/networkUtils.ts +270 -14
- package/src/utils/pro2Wallpaper.ts +109 -0
- package/src/utils/tracing.ts +3 -1
- package/dist/api/GetDeviceInfo.d.ts +0 -9
- package/dist/api/GetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/DevReboot.d.ts +0 -7
- package/dist/api/protocol-v2/DevReboot.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts +0 -29
- package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +0 -7
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +0 -1
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +0 -6
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/FilesystemDiskControl.d.ts +0 -13
- package/dist/api/protocol-v2/FilesystemDiskControl.d.ts.map +0 -1
- package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +0 -1
- package/dist/api/protocol-v2/GetProtoVersion.d.ts +0 -6
- package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +0 -1
- package/dist/deviceProfile/buildDeviceProfile.d.ts +0 -21
- package/dist/deviceProfile/buildDeviceProfile.d.ts.map +0 -1
- package/dist/types/api/getDeviceInfo.d.ts +0 -85
- package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
- package/src/api/GetDeviceInfo.ts +0 -145
- package/src/api/protocol-v2/DevReboot.ts +0 -24
- package/src/api/protocol-v2/DeviceGetDeviceInfo.ts +0 -118
- package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +0 -29
- package/src/api/protocol-v2/FilesystemDiskControl.ts +0 -50
- package/src/deviceProfile/buildDeviceProfile.ts +0 -334
- package/src/types/api/getDeviceInfo.ts +0 -99
package/src/device/Device.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import EventEmitter from 'events';
|
|
2
2
|
import semver from 'semver';
|
|
3
|
-
import { Enum_Capability } from '@onekeyfe/hd-transport';
|
|
3
|
+
import { DeviceRebootType, Enum_Capability } from '@onekeyfe/hd-transport';
|
|
4
4
|
import {
|
|
5
5
|
EDeviceType,
|
|
6
6
|
ERRORS,
|
|
@@ -9,16 +9,18 @@ import {
|
|
|
9
9
|
HardwareError,
|
|
10
10
|
HardwareErrorCode,
|
|
11
11
|
createDeferred,
|
|
12
|
+
createDeviceNotSupportMethodError,
|
|
12
13
|
} from '@onekeyfe/hd-shared';
|
|
13
14
|
|
|
14
15
|
import {
|
|
15
16
|
LoggerNames,
|
|
16
17
|
getDeviceBLEFirmwareVersion,
|
|
17
18
|
getDeviceBleName,
|
|
19
|
+
getDeviceBootloaderVersion,
|
|
18
20
|
getDeviceFirmwareVersion,
|
|
19
21
|
getDeviceLabel,
|
|
22
|
+
getDeviceSerialNo,
|
|
20
23
|
getDeviceType,
|
|
21
|
-
getDeviceUUID,
|
|
22
24
|
getFirmwareType,
|
|
23
25
|
getLogger,
|
|
24
26
|
} from '../utils';
|
|
@@ -31,9 +33,24 @@ import {
|
|
|
31
33
|
import { generateInstanceId } from '../utils/tracing';
|
|
32
34
|
// eslint-disable-next-line import/no-cycle
|
|
33
35
|
import { DeviceCommands } from './DeviceCommands';
|
|
36
|
+
import { mergeDeviceFeaturesPatch } from './DeviceFeaturesState';
|
|
37
|
+
import {
|
|
38
|
+
mapDeviceSettingsToState,
|
|
39
|
+
mapFeaturesToState,
|
|
40
|
+
mapProtocolV1OnekeyFeaturesToState,
|
|
41
|
+
mapProtocolV2DeviceInfoToState,
|
|
42
|
+
mapProtocolV2DeviceStatusToState,
|
|
43
|
+
} from './DeviceStateMapper';
|
|
44
|
+
import { projectFeatures } from './DeviceStateProjector';
|
|
45
|
+
import { DeviceStateStore, createPublicDeviceState } from './DeviceStateStore';
|
|
46
|
+
import { cloneDeviceState } from './cloneDeviceState';
|
|
47
|
+
import { deviceWalletSessionStore } from './DeviceWalletSessionStore';
|
|
34
48
|
import {
|
|
35
49
|
type DeviceFirmwareRange,
|
|
36
50
|
DeviceModelToTypes,
|
|
51
|
+
type DeviceStateEvent,
|
|
52
|
+
type DeviceStatePatch,
|
|
53
|
+
type DeviceStateUpdateSource,
|
|
37
54
|
DeviceTypeToModels,
|
|
38
55
|
type Device as DeviceTyped,
|
|
39
56
|
EOneKeyDeviceMode,
|
|
@@ -50,12 +67,18 @@ import TransportManager from '../data-manager/TransportManager';
|
|
|
50
67
|
import { toHardened } from '../api/helpers/pathUtils';
|
|
51
68
|
import { existCapability } from '../utils/capabilitieUtils';
|
|
52
69
|
import {
|
|
53
|
-
|
|
70
|
+
PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST,
|
|
71
|
+
PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST,
|
|
72
|
+
PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
|
|
73
|
+
type ProtocolV2RuntimeMode,
|
|
74
|
+
getProtocolV2RuntimeMode,
|
|
54
75
|
requestProtocolV2DeviceInfo,
|
|
76
|
+
requestProtocolV2DeviceStatus,
|
|
55
77
|
} from '../protocols/protocol-v2/features';
|
|
56
|
-
import { buildProtocolV1FeaturesPayload
|
|
78
|
+
import { buildProtocolV1FeaturesPayload } from '../deviceProfile';
|
|
57
79
|
|
|
58
80
|
import type { PROTO } from '../constants';
|
|
81
|
+
import type { DeviceStateReadOptions } from '../types/api/getDeviceState';
|
|
59
82
|
import type {
|
|
60
83
|
DeviceButtonRequestPayload,
|
|
61
84
|
DeviceFeaturesPayload,
|
|
@@ -65,6 +88,7 @@ import type { PassphrasePromptResponse } from './DeviceCommands';
|
|
|
65
88
|
import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
|
|
66
89
|
import type {
|
|
67
90
|
OneKeyDeviceInfo as DeviceDescriptor,
|
|
91
|
+
DeviceStatus,
|
|
68
92
|
ProtocolV2DeviceInfo,
|
|
69
93
|
Success,
|
|
70
94
|
} from '@onekeyfe/hd-transport';
|
|
@@ -76,6 +100,9 @@ export type InitOptions = {
|
|
|
76
100
|
passphraseState?: string;
|
|
77
101
|
deriveCardano?: boolean;
|
|
78
102
|
connectProtocol?: HardwareConnectProtocol;
|
|
103
|
+
protocolV2DeviceInfoTimeoutMs?: number;
|
|
104
|
+
/** Refresh Protocol V2 runtime state before returning discovery results. */
|
|
105
|
+
refreshRuntimeState?: boolean;
|
|
79
106
|
};
|
|
80
107
|
|
|
81
108
|
export type RunOptions = {
|
|
@@ -92,9 +119,11 @@ const Log = getLogger(LoggerNames.Device);
|
|
|
92
119
|
|
|
93
120
|
export interface DeviceEvents {
|
|
94
121
|
[DEVICE.PIN]: [Device, PROTO.PinMatrixRequestType | undefined, (err: any, pin: string) => void];
|
|
95
|
-
[DEVICE.PASSPHRASE_ON_DEVICE]: [Device,
|
|
122
|
+
[DEVICE.PASSPHRASE_ON_DEVICE]: [Device, PassphraseRequestPayload?];
|
|
123
|
+
[DEVICE.ATTACH_PIN_ON_DEVICE]: [Device, PassphraseRequestPayload?];
|
|
96
124
|
[DEVICE.BUTTON]: [Device, DeviceButtonRequestPayload];
|
|
97
125
|
[DEVICE.FEATURES]: [Device, DeviceFeaturesPayload];
|
|
126
|
+
[DEVICE.STATE]: [Device, DeviceStateEvent];
|
|
98
127
|
[DEVICE.PASSPHRASE]: [
|
|
99
128
|
Device,
|
|
100
129
|
PassphraseRequestPayload,
|
|
@@ -118,8 +147,6 @@ export interface Device {
|
|
|
118
147
|
emit<K extends keyof DeviceEvents>(type: K, ...args: DeviceEvents[K]): boolean;
|
|
119
148
|
}
|
|
120
149
|
|
|
121
|
-
const deviceSessionCache: Record<string, string> = {};
|
|
122
|
-
|
|
123
150
|
/**
|
|
124
151
|
* Pre-populate the device session cache with a known session ID.
|
|
125
152
|
*
|
|
@@ -137,8 +164,7 @@ export function preloadSessionCache(
|
|
|
137
164
|
passphraseState: string,
|
|
138
165
|
sessionId: string
|
|
139
166
|
): void {
|
|
140
|
-
|
|
141
|
-
deviceSessionCache[key] = sessionId;
|
|
167
|
+
deviceWalletSessionStore.set(deviceId, passphraseState, sessionId);
|
|
142
168
|
}
|
|
143
169
|
|
|
144
170
|
export class Device extends EventEmitter {
|
|
@@ -184,22 +210,51 @@ export class Device extends EventEmitter {
|
|
|
184
210
|
*/
|
|
185
211
|
private deviceAcquired = false;
|
|
186
212
|
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
213
|
+
/** Canonical device-state cache; legacy Features is a compatibility projection. */
|
|
214
|
+
private stateStore = new DeviceStateStore();
|
|
215
|
+
|
|
216
|
+
/** Force the next initialization to reload DeviceInfo after reconnect or reboot. */
|
|
217
|
+
private protocolV2StateNeedsReload = false;
|
|
218
|
+
|
|
219
|
+
get state() {
|
|
220
|
+
return this.stateStore.getState();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
get features(): Features | undefined {
|
|
224
|
+
if (!this.state) return undefined;
|
|
225
|
+
const features = projectFeatures(this.state);
|
|
226
|
+
const sessionCacheDeviceKey =
|
|
227
|
+
this.state.identity.deviceId ||
|
|
228
|
+
(this.isProtocolV2()
|
|
229
|
+
? this.originalDescriptor.path || this.originalDescriptor.id
|
|
230
|
+
: undefined);
|
|
231
|
+
const sessionId =
|
|
232
|
+
sessionCacheDeviceKey && this.passphraseState
|
|
233
|
+
? deviceWalletSessionStore.get(sessionCacheDeviceKey, this.passphraseState)
|
|
234
|
+
: undefined;
|
|
235
|
+
return sessionId
|
|
236
|
+
? {
|
|
237
|
+
...features,
|
|
238
|
+
sessionId,
|
|
239
|
+
session_id: sessionId,
|
|
240
|
+
passphraseState: this.passphraseState,
|
|
241
|
+
}
|
|
242
|
+
: features;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
set features(features: Features | undefined) {
|
|
246
|
+
this.stateStore = new DeviceStateStore();
|
|
247
|
+
if (features) {
|
|
248
|
+
this.stateStore.update(mapFeaturesToState(features), 'compatibility');
|
|
249
|
+
const { passphraseState } = features;
|
|
250
|
+
const sessionId = features.sessionId ?? features.session_id;
|
|
251
|
+
const deviceKey = this.getSessionCacheDeviceKey(features.deviceId ?? undefined);
|
|
252
|
+
if (passphraseState && sessionId && deviceKey) {
|
|
253
|
+
this.passphraseState = passphraseState;
|
|
254
|
+
deviceWalletSessionStore.set(deviceKey, passphraseState, sessionId);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
203
258
|
|
|
204
259
|
runPromise?: Deferred<void> | null;
|
|
205
260
|
|
|
@@ -261,14 +316,18 @@ export class Device extends EventEmitter {
|
|
|
261
316
|
const bleName = this.getCurrentBleName();
|
|
262
317
|
const label = this.getCurrentLabel();
|
|
263
318
|
const serialNo = this.getCurrentSerialNo();
|
|
319
|
+
const connectId = this.getConnectId();
|
|
264
320
|
const deviceId = this.getCurrentDeviceId() || null;
|
|
265
321
|
|
|
266
|
-
const features = this
|
|
322
|
+
const { features } = this;
|
|
323
|
+
const state = this.state ? createPublicDeviceState(this.state) : undefined;
|
|
267
324
|
|
|
268
325
|
return {
|
|
269
|
-
/** Android uses
|
|
270
|
-
connectId: DataManager.isBleConnect(env) ? this.mainId || null :
|
|
271
|
-
/**
|
|
326
|
+
/** Android uses a MAC address, while iOS and USB use transport-specific identifiers. */
|
|
327
|
+
connectId: DataManager.isBleConnect(env) ? this.mainId || null : connectId,
|
|
328
|
+
/** Stable physical-device identity. */
|
|
329
|
+
serialNo,
|
|
330
|
+
/** @deprecated Use serialNo instead. */
|
|
272
331
|
uuid: serialNo,
|
|
273
332
|
commType: this.originalDescriptor.commType,
|
|
274
333
|
sdkInstanceId: this.sdkInstanceId,
|
|
@@ -283,7 +342,7 @@ export class Device extends EventEmitter {
|
|
|
283
342
|
label: label || 'OneKey',
|
|
284
343
|
mode: this.getMode(),
|
|
285
344
|
features,
|
|
286
|
-
|
|
345
|
+
state,
|
|
287
346
|
firmwareVersion: this.getFirmwareVersion(),
|
|
288
347
|
bleFirmwareVersion: this.getBLEFirmwareVersion(),
|
|
289
348
|
unavailableCapabilities: this.unavailableCapabilities,
|
|
@@ -325,18 +384,20 @@ export class Device extends EventEmitter {
|
|
|
325
384
|
});
|
|
326
385
|
}
|
|
327
386
|
|
|
328
|
-
async acquire(
|
|
387
|
+
async acquire(
|
|
388
|
+
connectProtocol?: HardwareConnectProtocol,
|
|
389
|
+
options?: { throwOnRunPromiseError?: boolean }
|
|
390
|
+
) {
|
|
329
391
|
const env = DataManager.getSettings('env');
|
|
330
392
|
const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
|
|
331
393
|
const expectedProtocol = connectProtocol ?? this.originalDescriptor.protocolType;
|
|
332
394
|
try {
|
|
333
395
|
let acquireResult: unknown;
|
|
334
396
|
if (DataManager.isBleConnect(env)) {
|
|
335
|
-
//
|
|
336
|
-
//
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
// 因此对 BLE acquire 恒清理是有意为之。
|
|
397
|
+
// acquire starts a new BLE session. Any previous runPromise belongs to a dead
|
|
398
|
+
// session, such as an interrupted probe or firmware-update reboot, and would
|
|
399
|
+
// otherwise block the new session. Device cannot distinguish recovery from a
|
|
400
|
+
// regular acquire, so BLE always clears it intentionally.
|
|
340
401
|
acquireResult = await this.deviceConnector?.acquire(
|
|
341
402
|
this.originalDescriptor.id,
|
|
342
403
|
undefined,
|
|
@@ -374,6 +435,9 @@ export class Device extends EventEmitter {
|
|
|
374
435
|
|
|
375
436
|
this.commands = new DeviceCommands(this, this.mainId ?? '');
|
|
376
437
|
} catch (error) {
|
|
438
|
+
if (options?.throwOnRunPromiseError) {
|
|
439
|
+
throw error;
|
|
440
|
+
}
|
|
377
441
|
if (this.runPromise) {
|
|
378
442
|
this.runPromise.reject(error);
|
|
379
443
|
} else {
|
|
@@ -474,12 +538,11 @@ export class Device extends EventEmitter {
|
|
|
474
538
|
}
|
|
475
539
|
|
|
476
540
|
/**
|
|
477
|
-
*
|
|
541
|
+
* Canonical protocol discriminator.
|
|
478
542
|
*
|
|
479
|
-
* descriptor.protocolType
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
* 或从 features 反推。
|
|
543
|
+
* descriptor.protocolType is established by active probing; V2 features are mapped
|
|
544
|
+
* from DeviceInfoGet. All protocol branches must use this method instead of reading
|
|
545
|
+
* originalDescriptor.protocolType directly or inferring a protocol from features.
|
|
483
546
|
*/
|
|
484
547
|
getProtocol(): 'V1' | 'V2' {
|
|
485
548
|
return this.originalDescriptor.protocolType === 'V2' ? 'V2' : 'V1';
|
|
@@ -498,7 +561,16 @@ export class Device extends EventEmitter {
|
|
|
498
561
|
}
|
|
499
562
|
|
|
500
563
|
getCurrentSerialNo() {
|
|
501
|
-
return
|
|
564
|
+
return getDeviceSerialNo(this.features);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
getConnectId() {
|
|
568
|
+
const serialNo = this.getCurrentSerialNo();
|
|
569
|
+
if (serialNo) return serialNo;
|
|
570
|
+
|
|
571
|
+
// connectId is an internal routing key. Falling back to the transport descriptor
|
|
572
|
+
// does not change the business meaning of features.serialNo or deviceId.
|
|
573
|
+
return this.originalDescriptor.path || this.originalDescriptor.id || '';
|
|
502
574
|
}
|
|
503
575
|
|
|
504
576
|
getCurrentBleName() {
|
|
@@ -526,6 +598,11 @@ export class Device extends EventEmitter {
|
|
|
526
598
|
return getDeviceBLEFirmwareVersion(this.features).join('.');
|
|
527
599
|
}
|
|
528
600
|
|
|
601
|
+
getCurrentBootloaderVersionString() {
|
|
602
|
+
if (!this.features) return undefined;
|
|
603
|
+
return getDeviceBootloaderVersion(this.features).join('.');
|
|
604
|
+
}
|
|
605
|
+
|
|
529
606
|
getCurrentSafetyChecks() {
|
|
530
607
|
return this.features?.safetyChecks;
|
|
531
608
|
}
|
|
@@ -591,9 +668,8 @@ export class Device extends EventEmitter {
|
|
|
591
668
|
}
|
|
592
669
|
|
|
593
670
|
supportModifyHomescreen(): SupportFeatureType {
|
|
594
|
-
// Pro2
|
|
595
|
-
//
|
|
596
|
-
// 包含 homescreen 字段,V2 固件从首个版本即支持修改主屏。
|
|
671
|
+
// Pro2 has an independent 1.x version line and must not use the Touch/Pro 3.4.0
|
|
672
|
+
// threshold. ApplySettings includes homescreen from the first V2 firmware version.
|
|
597
673
|
if (this.isProtocolV2()) {
|
|
598
674
|
return { support: true };
|
|
599
675
|
}
|
|
@@ -611,13 +687,6 @@ export class Device extends EventEmitter {
|
|
|
611
687
|
};
|
|
612
688
|
}
|
|
613
689
|
|
|
614
|
-
private generateStateKey(deviceId: string, passphraseState?: string) {
|
|
615
|
-
if (passphraseState) {
|
|
616
|
-
return `${deviceId}@${passphraseState}`;
|
|
617
|
-
}
|
|
618
|
-
return deviceId;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
690
|
private getSessionCacheDeviceKey(_deviceId?: string) {
|
|
622
691
|
const deviceId = _deviceId || this.getCurrentDeviceId();
|
|
623
692
|
if (deviceId) return deviceId;
|
|
@@ -627,13 +696,22 @@ export class Device extends EventEmitter {
|
|
|
627
696
|
return undefined;
|
|
628
697
|
}
|
|
629
698
|
|
|
699
|
+
private reconcileSessionCacheDeviceIdentity(previousDeviceId?: string) {
|
|
700
|
+
deviceWalletSessionStore.reconcileDeviceIdentity({
|
|
701
|
+
temporaryKey: this.isProtocolV2()
|
|
702
|
+
? this.originalDescriptor.path || this.originalDescriptor.id
|
|
703
|
+
: undefined,
|
|
704
|
+
previousDeviceId,
|
|
705
|
+
nextDeviceId: this.getCurrentDeviceId(),
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
|
|
630
709
|
getInternalState(_deviceId?: string) {
|
|
631
|
-
Log.debug('getInternalState session cache: ', deviceSessionCache);
|
|
632
710
|
Log.debug(
|
|
633
711
|
'getInternalState session param: ',
|
|
634
712
|
`device_id: ${_deviceId}`,
|
|
635
713
|
`features.deviceId: ${this.features?.deviceId}`,
|
|
636
|
-
`
|
|
714
|
+
`hasPassphraseState: ${Boolean(this.passphraseState)}`
|
|
637
715
|
);
|
|
638
716
|
|
|
639
717
|
const deviceId = this.getSessionCacheDeviceKey(_deviceId);
|
|
@@ -646,8 +724,7 @@ export class Device extends EventEmitter {
|
|
|
646
724
|
// downstream call carries it and hits the primary lookup below.
|
|
647
725
|
if (!this.passphraseState) return undefined;
|
|
648
726
|
|
|
649
|
-
|
|
650
|
-
return deviceSessionCache[usePassKey];
|
|
727
|
+
return deviceWalletSessionStore.get(deviceId, this.passphraseState);
|
|
651
728
|
}
|
|
652
729
|
|
|
653
730
|
// attach to pin to fix internal state
|
|
@@ -662,40 +739,30 @@ export class Device extends EventEmitter {
|
|
|
662
739
|
'updateInternalState session param: ',
|
|
663
740
|
`device_id: ${deviceId}`,
|
|
664
741
|
`enablePassphrase: ${enablePassphrase}`,
|
|
665
|
-
`
|
|
666
|
-
`
|
|
667
|
-
`
|
|
742
|
+
`hasPassphraseState: ${Boolean(passphraseState)}`,
|
|
743
|
+
`hasSessionId: ${Boolean(sessionId)}`,
|
|
744
|
+
`hasFeaturesSessionId: ${Boolean(featuresSessionId)}`
|
|
668
745
|
);
|
|
669
746
|
|
|
670
747
|
const cacheDeviceKey = this.getSessionCacheDeviceKey(deviceId);
|
|
671
748
|
if (!cacheDeviceKey) return;
|
|
672
749
|
|
|
673
750
|
if (enablePassphrase) {
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
} else if (featuresSessionId) {
|
|
678
|
-
deviceSessionCache[this.generateStateKey(cacheDeviceKey, passphraseState)] =
|
|
679
|
-
featuresSessionId;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// delete the old sessionId
|
|
684
|
-
const oldKey = `${cacheDeviceKey}`;
|
|
685
|
-
if (deviceSessionCache[oldKey]) {
|
|
686
|
-
delete deviceSessionCache[oldKey];
|
|
751
|
+
const walletSessionId =
|
|
752
|
+
sessionId || featuresSessionId || deviceWalletSessionStore.getPending(cacheDeviceKey);
|
|
753
|
+
deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId ?? undefined);
|
|
687
754
|
}
|
|
688
755
|
|
|
689
|
-
|
|
756
|
+
deviceWalletSessionStore.deletePending(cacheDeviceKey);
|
|
690
757
|
}
|
|
691
758
|
|
|
692
759
|
private setInternalState(state: string, initSession?: boolean) {
|
|
693
760
|
Log.debug(
|
|
694
761
|
'setInternalState session param: ',
|
|
695
|
-
`
|
|
762
|
+
`hasState: ${Boolean(state)}`,
|
|
696
763
|
`initSession: ${initSession}`,
|
|
697
764
|
`deviceId: ${this.features?.deviceId}`,
|
|
698
|
-
`
|
|
765
|
+
`hasPassphraseState: ${Boolean(this.passphraseState)}`
|
|
699
766
|
);
|
|
700
767
|
|
|
701
768
|
if (!this.passphraseState && !initSession) return;
|
|
@@ -703,12 +770,11 @@ export class Device extends EventEmitter {
|
|
|
703
770
|
const deviceId = this.getSessionCacheDeviceKey();
|
|
704
771
|
if (!deviceId) return;
|
|
705
772
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
if (
|
|
709
|
-
|
|
773
|
+
if (this.passphraseState) {
|
|
774
|
+
deviceWalletSessionStore.set(deviceId, this.passphraseState, state);
|
|
775
|
+
} else if (initSession) {
|
|
776
|
+
deviceWalletSessionStore.setPending(deviceId, state);
|
|
710
777
|
}
|
|
711
|
-
Log.debug('setInternalState done session cache: ', deviceSessionCache);
|
|
712
778
|
}
|
|
713
779
|
|
|
714
780
|
clearInternalState(_deviceId?: string) {
|
|
@@ -716,27 +782,27 @@ export class Device extends EventEmitter {
|
|
|
716
782
|
|
|
717
783
|
const deviceId = this.getSessionCacheDeviceKey(_deviceId);
|
|
718
784
|
if (!deviceId) return;
|
|
719
|
-
|
|
720
|
-
delete deviceSessionCache[key];
|
|
785
|
+
deviceWalletSessionStore.deletePending(deviceId);
|
|
721
786
|
|
|
722
787
|
if (this.passphraseState) {
|
|
723
|
-
|
|
724
|
-
delete deviceSessionCache[usePassKey];
|
|
788
|
+
deviceWalletSessionStore.delete(deviceId, this.passphraseState);
|
|
725
789
|
}
|
|
726
790
|
}
|
|
727
791
|
|
|
728
792
|
async initialize(options?: InitOptions) {
|
|
729
|
-
// Protocol V2
|
|
793
|
+
// Protocol V2 does not support legacy Initialize; use its dedicated flow.
|
|
730
794
|
if (this.isProtocolV2()) {
|
|
731
795
|
this.passphraseState = options?.passphraseState;
|
|
732
|
-
if (this.
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
796
|
+
if (this.state && !options?.initSession && !this.protocolV2StateNeedsReload) {
|
|
797
|
+
if (this.features?.bootloaderMode) {
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
// Normal calls reuse the cache. Explicit getDeviceState refreshes, unlock flow,
|
|
801
|
+
// and device events update dynamic state without polling on every SDK call.
|
|
737
802
|
return;
|
|
738
803
|
}
|
|
739
|
-
await this._initializeProtocolV2();
|
|
804
|
+
await this._initializeProtocolV2(options);
|
|
805
|
+
this.protocolV2StateNeedsReload = false;
|
|
740
806
|
return;
|
|
741
807
|
}
|
|
742
808
|
|
|
@@ -786,57 +852,38 @@ export class Device extends EventEmitter {
|
|
|
786
852
|
/**
|
|
787
853
|
* Device initialization over Protocol V2.
|
|
788
854
|
*
|
|
789
|
-
* Protocol V2
|
|
790
|
-
*
|
|
855
|
+
* Protocol V2 bypasses legacy Initialize/GetFeatures and builds its canonical
|
|
856
|
+
* features state directly from DeviceInfoGet.
|
|
791
857
|
*/
|
|
792
|
-
private async _initializeProtocolV2() {
|
|
858
|
+
private async _initializeProtocolV2(options?: InitOptions) {
|
|
793
859
|
Log.debug('Initialize device via Protocol V2 features adapter');
|
|
794
860
|
|
|
795
861
|
try {
|
|
796
|
-
//
|
|
797
|
-
//
|
|
798
|
-
// 且 reject 后底层调用仍会残留。
|
|
862
|
+
// typedCall applies the request timeout. An outer Promise.race would leak its
|
|
863
|
+
// timer and leave the underlying call active after rejection.
|
|
799
864
|
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
800
865
|
commands: this.commands,
|
|
866
|
+
timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
|
|
801
867
|
});
|
|
802
|
-
//
|
|
803
|
-
//
|
|
804
|
-
const features = this.
|
|
868
|
+
// The default request excludes SE/hash data and therefore uses basic scope.
|
|
869
|
+
// Full version and verification data require getDeviceState({ scope: 'firmware' }).
|
|
870
|
+
const features = await this.probeProtocolV2RuntimeState(
|
|
871
|
+
deviceInfo,
|
|
872
|
+
options?.protocolV2DeviceInfoTimeoutMs
|
|
873
|
+
);
|
|
805
874
|
Log.debug('Protocol V2 features:', features);
|
|
806
|
-
this.featuresNeedsReload = false;
|
|
807
875
|
} catch (error) {
|
|
808
876
|
Log.error('Protocol V2 initialization failed:', error);
|
|
809
877
|
throw error;
|
|
810
878
|
}
|
|
811
879
|
}
|
|
812
880
|
|
|
813
|
-
/**
|
|
814
|
-
* Protocol V2 的轻量状态刷新(每次 run 前调用)。
|
|
815
|
-
*
|
|
816
|
-
* 请求 hw + bt + status(不含 fw/SE target):status 提供 init_states / label /
|
|
817
|
-
* passphrase_protection 等会在设备端变化的字段;hw/bt 提供 serialNo / bleName。
|
|
818
|
-
* versions 为空时按字段级合并保留旧值,verify 数据不会被降级。
|
|
819
|
-
*/
|
|
820
|
-
private async _refreshProtocolV2Status() {
|
|
821
|
-
try {
|
|
822
|
-
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
823
|
-
commands: this.commands,
|
|
824
|
-
request: PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
|
|
825
|
-
});
|
|
826
|
-
const features = this.updateProtocolV2Features(deviceInfo);
|
|
827
|
-
Log.debug('Protocol V2 features (status refresh):', features);
|
|
828
|
-
} catch (error) {
|
|
829
|
-
Log.error('Protocol V2 status refresh failed:', error);
|
|
830
|
-
throw error;
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
|
|
834
881
|
async getFeatures() {
|
|
835
882
|
if (this.isProtocolV2()) {
|
|
836
883
|
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
837
884
|
commands: this.commands,
|
|
838
885
|
});
|
|
839
|
-
return this.
|
|
886
|
+
return this.probeProtocolV2RuntimeState(deviceInfo);
|
|
840
887
|
}
|
|
841
888
|
|
|
842
889
|
const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
|
|
@@ -844,7 +891,82 @@ export class Device extends EventEmitter {
|
|
|
844
891
|
return this.features;
|
|
845
892
|
}
|
|
846
893
|
|
|
894
|
+
async getDeviceState(params: DeviceStateReadOptions = {}) {
|
|
895
|
+
const refresh = new Set(params.refreshSections ?? []);
|
|
896
|
+
const getProtocolV2DeviceInfoRequest = () => {
|
|
897
|
+
if (refresh.has('verification')) return PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST;
|
|
898
|
+
if (refresh.has('versions')) return PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST;
|
|
899
|
+
return PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST;
|
|
900
|
+
};
|
|
901
|
+
let initializedWithDeviceInfo = false;
|
|
902
|
+
let refreshedDeviceInfo: ProtocolV2DeviceInfo | undefined;
|
|
903
|
+
|
|
904
|
+
if (!this.state) {
|
|
905
|
+
if (this.isProtocolV2()) {
|
|
906
|
+
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
907
|
+
commands: this.commands,
|
|
908
|
+
request: getProtocolV2DeviceInfoRequest(),
|
|
909
|
+
});
|
|
910
|
+
await this.probeProtocolV2RuntimeState(deviceInfo);
|
|
911
|
+
refreshedDeviceInfo = deviceInfo;
|
|
912
|
+
initializedWithDeviceInfo = true;
|
|
913
|
+
} else {
|
|
914
|
+
await this.getFeatures();
|
|
915
|
+
}
|
|
916
|
+
} else if (!this.isProtocolV2() && refresh.size > 0) {
|
|
917
|
+
await this.getFeatures();
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
if (!this.isProtocolV2() && refresh.has('verification')) {
|
|
921
|
+
const { message } = await this.commands.typedCall('OnekeyGetFeatures', 'OnekeyFeatures');
|
|
922
|
+
this.updateState(mapProtocolV1OnekeyFeaturesToState(message), 'device-info');
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
if (this.isProtocolV2()) {
|
|
926
|
+
const refreshDeviceInfo =
|
|
927
|
+
refresh.has('identity') || refresh.has('versions') || refresh.has('verification');
|
|
928
|
+
if (refreshDeviceInfo && !initializedWithDeviceInfo) {
|
|
929
|
+
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
930
|
+
commands: this.commands,
|
|
931
|
+
request: getProtocolV2DeviceInfoRequest(),
|
|
932
|
+
});
|
|
933
|
+
refreshedDeviceInfo = deviceInfo;
|
|
934
|
+
if (!refresh.has('status')) {
|
|
935
|
+
this.updateState(
|
|
936
|
+
mapProtocolV2DeviceInfoToState(deviceInfo, this.state?.status.mode),
|
|
937
|
+
'device-info'
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
if (refresh.has('status') && !initializedWithDeviceInfo) {
|
|
943
|
+
const deviceInfo =
|
|
944
|
+
refreshedDeviceInfo ??
|
|
945
|
+
(await requestProtocolV2DeviceInfo({
|
|
946
|
+
commands: this.commands,
|
|
947
|
+
request: getProtocolV2DeviceInfoRequest(),
|
|
948
|
+
}));
|
|
949
|
+
await this.probeProtocolV2RuntimeState(deviceInfo);
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
if (refresh.has('settings') && this.state?.status.mode === 'normal') {
|
|
953
|
+
const { message } = await this.commands.typedCall(
|
|
954
|
+
'DeviceSettingsGet',
|
|
955
|
+
'DeviceSettings',
|
|
956
|
+
{}
|
|
957
|
+
);
|
|
958
|
+
this.updateState(mapDeviceSettingsToState(message), 'settings-read');
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
if (!this.state) {
|
|
963
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed);
|
|
964
|
+
}
|
|
965
|
+
return params.includeRaw ? cloneDeviceState(this.state) : createPublicDeviceState(this.state);
|
|
966
|
+
}
|
|
967
|
+
|
|
847
968
|
_updateFeatures(protoFeatures: PROTO.Features | Features, initSession?: boolean) {
|
|
969
|
+
const previousDeviceId = this.getCurrentDeviceId();
|
|
848
970
|
let feat =
|
|
849
971
|
'protocol' in protoFeatures
|
|
850
972
|
? protoFeatures
|
|
@@ -854,26 +976,151 @@ export class Device extends EventEmitter {
|
|
|
854
976
|
if (this.features?.sessionId && !feat.sessionId) {
|
|
855
977
|
feat.sessionId = this.features.sessionId;
|
|
856
978
|
}
|
|
857
|
-
if (this.getCurrentDeviceId() && feat.sessionId) {
|
|
858
|
-
this.setInternalState(feat.sessionId, initSession);
|
|
859
|
-
}
|
|
860
979
|
feat.unlocked = feat.unlocked ?? true;
|
|
861
980
|
|
|
862
981
|
feat = fixFeaturesFirmwareVersion(feat);
|
|
863
982
|
|
|
864
|
-
this.
|
|
865
|
-
this.
|
|
866
|
-
|
|
983
|
+
this.updateState(mapFeaturesToState(feat), 'initialize');
|
|
984
|
+
this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
|
|
985
|
+
if (feat.deviceId && feat.sessionId) {
|
|
986
|
+
this.setInternalState(feat.sessionId, initSession);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
updateState(patch: DeviceStatePatch, source: DeviceStateUpdateSource) {
|
|
991
|
+
const result = this.stateStore.update(patch, source);
|
|
992
|
+
if (result.changedKeys.length === 0) return result.state;
|
|
993
|
+
|
|
994
|
+
const event: DeviceStateEvent = {
|
|
995
|
+
connectId: this.getConnectId() ?? null,
|
|
996
|
+
state: createPublicDeviceState(result.state),
|
|
997
|
+
revision: result.revision,
|
|
998
|
+
source,
|
|
999
|
+
changedKeys: result.changedKeys,
|
|
1000
|
+
};
|
|
1001
|
+
Log.debug('Device state patch committed', {
|
|
1002
|
+
source,
|
|
1003
|
+
keys: result.changedKeys,
|
|
1004
|
+
});
|
|
1005
|
+
this.emit(DEVICE.STATE, this, event);
|
|
1006
|
+
if (result.state.protocol === 'V1') {
|
|
1007
|
+
this.emit(DEVICE.FEATURES, this, projectFeatures(result.state));
|
|
1008
|
+
}
|
|
1009
|
+
return result.state;
|
|
867
1010
|
}
|
|
868
1011
|
|
|
869
|
-
|
|
870
|
-
const
|
|
871
|
-
|
|
1012
|
+
updateFeaturesPatch(patch: Partial<Features>, source: DeviceStateUpdateSource) {
|
|
1013
|
+
const currentFeatures = this.features;
|
|
1014
|
+
if (!currentFeatures) return undefined;
|
|
1015
|
+
|
|
1016
|
+
const features = mergeDeviceFeaturesPatch(currentFeatures, patch);
|
|
1017
|
+
if (features === currentFeatures) return currentFeatures;
|
|
1018
|
+
|
|
1019
|
+
const normalized = fixFeaturesFirmwareVersion(features);
|
|
1020
|
+
this.updateState(mapFeaturesToState(normalized), source);
|
|
1021
|
+
return this.features;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
async probeProtocolV2RuntimeState(deviceInfo: ProtocolV2DeviceInfo, timeoutMs?: number) {
|
|
1025
|
+
let deviceStatus: DeviceStatus;
|
|
1026
|
+
try {
|
|
1027
|
+
deviceStatus = await requestProtocolV2DeviceStatus({
|
|
1028
|
+
commands: this.commands,
|
|
1029
|
+
timeoutMs,
|
|
1030
|
+
});
|
|
1031
|
+
} catch (error) {
|
|
1032
|
+
const runtimeMode = getProtocolV2RuntimeMode({
|
|
1033
|
+
deviceInfo,
|
|
1034
|
+
deviceStatusAvailable: false,
|
|
1035
|
+
});
|
|
1036
|
+
Log.debug('Protocol V2 DeviceStatusGet unavailable; use temporary loader fallback', {
|
|
1037
|
+
runtimeMode,
|
|
1038
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1039
|
+
});
|
|
1040
|
+
return this.updateProtocolV2Features(deviceInfo, null, runtimeMode);
|
|
1041
|
+
}
|
|
1042
|
+
return this.updateProtocolV2Features(deviceInfo, deviceStatus, 'normal');
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
updateProtocolV2Features(
|
|
1046
|
+
deviceInfo?: ProtocolV2DeviceInfo,
|
|
1047
|
+
deviceStatus?: DeviceStatus | null,
|
|
1048
|
+
runtimeMode?: ProtocolV2RuntimeMode
|
|
1049
|
+
) {
|
|
1050
|
+
const previousDeviceId = this.getCurrentDeviceId();
|
|
1051
|
+
const resolvedMode =
|
|
1052
|
+
runtimeMode ??
|
|
1053
|
+
(deviceStatus
|
|
1054
|
+
? getProtocolV2RuntimeMode({ deviceInfo, deviceStatusAvailable: true })
|
|
1055
|
+
: this.state?.status.mode);
|
|
1056
|
+
if (deviceInfo) {
|
|
1057
|
+
this.updateState(mapProtocolV2DeviceInfoToState(deviceInfo, resolvedMode), 'device-info');
|
|
1058
|
+
}
|
|
1059
|
+
if (deviceStatus) {
|
|
1060
|
+
this.updateState(mapProtocolV2DeviceStatusToState(deviceStatus), 'device-status');
|
|
1061
|
+
}
|
|
1062
|
+
this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
|
|
1063
|
+
return this.features as Features;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
updateProtocolV2Status(status: DeviceStatus) {
|
|
1067
|
+
const previousDeviceInfo = this.state?.raw?.protocolV2DeviceInfo;
|
|
1068
|
+
const previousStatus = this.state?.raw?.protocolV2DeviceStatus;
|
|
1069
|
+
return this.updateProtocolV2Features(previousDeviceInfo, {
|
|
1070
|
+
...previousStatus,
|
|
1071
|
+
...status,
|
|
1072
|
+
});
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
markTransportDisconnected() {
|
|
1076
|
+
if (!this.isProtocolV2()) return;
|
|
1077
|
+
this.protocolV2StateNeedsReload = true;
|
|
1078
|
+
this.clearPreInitialized();
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
markProtocolV2Reboot(rebootType: DeviceRebootType) {
|
|
1082
|
+
if (!this.isProtocolV2()) return;
|
|
1083
|
+
|
|
1084
|
+
this.protocolV2StateNeedsReload = true;
|
|
1085
|
+
this.clearPreInitialized();
|
|
1086
|
+
let loaderMode: 'bootloader' | 'romloader' | undefined;
|
|
1087
|
+
if (rebootType === DeviceRebootType.Bootloader) {
|
|
1088
|
+
loaderMode = 'bootloader';
|
|
1089
|
+
} else if (rebootType === DeviceRebootType.Romloader) {
|
|
1090
|
+
loaderMode = 'romloader';
|
|
1091
|
+
}
|
|
1092
|
+
if (loaderMode) {
|
|
1093
|
+
this.updateState(
|
|
1094
|
+
{
|
|
1095
|
+
identity: { deviceId: null },
|
|
1096
|
+
status: {
|
|
1097
|
+
mode: loaderMode,
|
|
1098
|
+
initialized: null,
|
|
1099
|
+
unlocked: null,
|
|
1100
|
+
firmwarePresent: null,
|
|
1101
|
+
backupRequired: null,
|
|
1102
|
+
noBackup: null,
|
|
1103
|
+
unfinishedBackup: null,
|
|
1104
|
+
recoveryMode: null,
|
|
1105
|
+
passphraseProtection: null,
|
|
1106
|
+
pinProtection: null,
|
|
1107
|
+
attachToPinEnabled: null,
|
|
1108
|
+
unlockedAttachPin: null,
|
|
1109
|
+
},
|
|
1110
|
+
raw: { protocolV2DeviceStatus: null },
|
|
1111
|
+
},
|
|
1112
|
+
'transport-reconnect'
|
|
1113
|
+
);
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
this.updateState(
|
|
1118
|
+
{
|
|
1119
|
+
status: { mode: 'normal', unlocked: null },
|
|
1120
|
+
raw: { protocolV2DeviceStatus: null },
|
|
1121
|
+
},
|
|
1122
|
+
'transport-reconnect'
|
|
872
1123
|
);
|
|
873
|
-
this.features = features;
|
|
874
|
-
this.featuresNeedsReload = false;
|
|
875
|
-
this.emit(DEVICE.FEATURES, this, features);
|
|
876
|
-
return features;
|
|
877
1124
|
}
|
|
878
1125
|
|
|
879
1126
|
/**
|
|
@@ -894,8 +1141,7 @@ export class Device extends EventEmitter {
|
|
|
894
1141
|
}
|
|
895
1142
|
|
|
896
1143
|
if (forceUpdate) {
|
|
897
|
-
//
|
|
898
|
-
// 不能让覆盖丢掉已探测的协议结果。
|
|
1144
|
+
// Enumerated descriptors may omit protocolType, so preserve an actively probed value.
|
|
899
1145
|
this.originalDescriptor = {
|
|
900
1146
|
...descriptor,
|
|
901
1147
|
protocolType: descriptor.protocolType ?? this.originalDescriptor.protocolType,
|
|
@@ -920,19 +1166,37 @@ export class Device extends EventEmitter {
|
|
|
920
1166
|
|
|
921
1167
|
options = parseRunOptions(options);
|
|
922
1168
|
|
|
923
|
-
|
|
924
|
-
|
|
1169
|
+
const runPromise = createDeferred<void>();
|
|
1170
|
+
this.runPromise = runPromise;
|
|
1171
|
+
this._runInner(fn, options, runPromise).catch(error => {
|
|
1172
|
+
if (this.runPromise === runPromise) {
|
|
1173
|
+
this.runPromise = null;
|
|
1174
|
+
}
|
|
1175
|
+
runPromise.reject(error);
|
|
1176
|
+
});
|
|
1177
|
+
return runPromise.promise;
|
|
925
1178
|
}
|
|
926
1179
|
|
|
927
|
-
async _runInner<T>(
|
|
1180
|
+
async _runInner<T>(
|
|
1181
|
+
fn: (() => Promise<T>) | undefined,
|
|
1182
|
+
options: RunOptions,
|
|
1183
|
+
runPromise: Deferred<void>
|
|
1184
|
+
) {
|
|
1185
|
+
const clearRunPromise = () => {
|
|
1186
|
+
if (this.runPromise === runPromise) {
|
|
1187
|
+
this.runPromise = null;
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
|
|
928
1191
|
if (!this.isUsedHere() || this.commands.disposed) {
|
|
929
1192
|
const env = DataManager.getSettings('env');
|
|
930
1193
|
if (env !== 'react-native') {
|
|
931
1194
|
try {
|
|
932
1195
|
await this.acquire(options.connectProtocol);
|
|
933
1196
|
} catch (error) {
|
|
934
|
-
|
|
935
|
-
|
|
1197
|
+
clearRunPromise();
|
|
1198
|
+
runPromise.reject(error);
|
|
1199
|
+
return;
|
|
936
1200
|
}
|
|
937
1201
|
|
|
938
1202
|
try {
|
|
@@ -942,16 +1206,19 @@ export class Device extends EventEmitter {
|
|
|
942
1206
|
}
|
|
943
1207
|
}
|
|
944
1208
|
} catch (error) {
|
|
945
|
-
this.
|
|
1209
|
+
await this.release();
|
|
1210
|
+
clearRunPromise();
|
|
946
1211
|
if (error instanceof HardwareError) {
|
|
947
|
-
|
|
1212
|
+
runPromise.reject(error);
|
|
1213
|
+
return;
|
|
948
1214
|
}
|
|
949
|
-
|
|
1215
|
+
runPromise.reject(
|
|
950
1216
|
ERRORS.TypedError(
|
|
951
1217
|
HardwareErrorCode.DeviceInitializeFailed,
|
|
952
1218
|
`Initialize failed: ${error.message as string}, code: ${error.code as string}`
|
|
953
1219
|
)
|
|
954
1220
|
);
|
|
1221
|
+
return;
|
|
955
1222
|
}
|
|
956
1223
|
} else if (env === 'react-native') {
|
|
957
1224
|
// TODO: implement react-native acquire
|
|
@@ -970,9 +1237,7 @@ export class Device extends EventEmitter {
|
|
|
970
1237
|
try {
|
|
971
1238
|
await fn();
|
|
972
1239
|
} catch (e) {
|
|
973
|
-
|
|
974
|
-
this.runPromise.reject(e);
|
|
975
|
-
}
|
|
1240
|
+
runPromise.reject(e);
|
|
976
1241
|
|
|
977
1242
|
if (
|
|
978
1243
|
e instanceof HardwareError &&
|
|
@@ -985,7 +1250,7 @@ export class Device extends EventEmitter {
|
|
|
985
1250
|
Log.debug(`error code ${e.errorCode} release device, mainId: ${this.mainId}`);
|
|
986
1251
|
}
|
|
987
1252
|
|
|
988
|
-
|
|
1253
|
+
clearRunPromise();
|
|
989
1254
|
return;
|
|
990
1255
|
}
|
|
991
1256
|
}
|
|
@@ -999,11 +1264,8 @@ export class Device extends EventEmitter {
|
|
|
999
1264
|
Log.debug('release device, mainId: ', this.mainId);
|
|
1000
1265
|
}
|
|
1001
1266
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
this.runPromise = null;
|
|
1267
|
+
runPromise.resolve();
|
|
1268
|
+
clearRunPromise();
|
|
1007
1269
|
}
|
|
1008
1270
|
|
|
1009
1271
|
async interruptionFromOutside() {
|
|
@@ -1042,22 +1304,23 @@ export class Device extends EventEmitter {
|
|
|
1042
1304
|
}
|
|
1043
1305
|
|
|
1044
1306
|
getMode() {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
return EOneKeyDeviceMode.backupMode;
|
|
1307
|
+
switch (this.state?.status.mode) {
|
|
1308
|
+
case 'bootloader':
|
|
1309
|
+
case 'romloader':
|
|
1310
|
+
return EOneKeyDeviceMode.bootloader;
|
|
1311
|
+
case 'notInitialized':
|
|
1312
|
+
return EOneKeyDeviceMode.notInitialized;
|
|
1313
|
+
case 'backupMode':
|
|
1314
|
+
return EOneKeyDeviceMode.backupMode;
|
|
1315
|
+
case 'normal':
|
|
1316
|
+
return EOneKeyDeviceMode.normal;
|
|
1317
|
+
default:
|
|
1318
|
+
break;
|
|
1058
1319
|
}
|
|
1059
1320
|
|
|
1060
|
-
|
|
1321
|
+
if (this.features?.bootloaderMode) return EOneKeyDeviceMode.bootloader;
|
|
1322
|
+
if (this.features?.initialized === false) return EOneKeyDeviceMode.notInitialized;
|
|
1323
|
+
if (this.features?.noBackup) return EOneKeyDeviceMode.backupMode;
|
|
1061
1324
|
return EOneKeyDeviceMode.normal;
|
|
1062
1325
|
}
|
|
1063
1326
|
|
|
@@ -1115,7 +1378,7 @@ export class Device extends EventEmitter {
|
|
|
1115
1378
|
// both allow and require cases might generate single unexpected mode
|
|
1116
1379
|
if (!this.isUnacquired()) {
|
|
1117
1380
|
// allow cases
|
|
1118
|
-
if (this.isBootloader() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
|
|
1381
|
+
if (this.isBootloader() && !this.isProtocolV2() && !allow.includes(UI_REQUEST.BOOTLOADER)) {
|
|
1119
1382
|
return UI_REQUEST.BOOTLOADER;
|
|
1120
1383
|
}
|
|
1121
1384
|
if (!this.isInitialized() && !allow.includes(UI_REQUEST.NOT_INITIALIZE)) {
|
|
@@ -1152,12 +1415,12 @@ export class Device extends EventEmitter {
|
|
|
1152
1415
|
|
|
1153
1416
|
async lockDevice(): Promise<Success> {
|
|
1154
1417
|
const res = await this.commands.typedCall('LockDevice', 'Success', {});
|
|
1418
|
+
this.updateState({ status: { unlocked: false } }, 'lock');
|
|
1155
1419
|
return res.message;
|
|
1156
1420
|
}
|
|
1157
1421
|
|
|
1158
1422
|
supportUnlockVersionRange(): DeviceFirmwareRange {
|
|
1159
|
-
//
|
|
1160
|
-
// 且 Protocol V2 固件从首个版本即支持 UnLockDevice(见 unlockDevice 的 isProtocolV2 短路)。
|
|
1423
|
+
// This range applies to Protocol V1 Pro devices; Pro2 has a dedicated unlock flow.
|
|
1161
1424
|
return {
|
|
1162
1425
|
pro: {
|
|
1163
1426
|
min: '4.15.0',
|
|
@@ -1166,6 +1429,26 @@ export class Device extends EventEmitter {
|
|
|
1166
1429
|
}
|
|
1167
1430
|
|
|
1168
1431
|
async unlockDevice() {
|
|
1432
|
+
if (this.isProtocolV2()) {
|
|
1433
|
+
try {
|
|
1434
|
+
await this.commands.typedCall('DeviceSessionAskPin', 'Success', undefined, {
|
|
1435
|
+
timeoutMs: 120_000,
|
|
1436
|
+
});
|
|
1437
|
+
} catch (error) {
|
|
1438
|
+
const errorText =
|
|
1439
|
+
error instanceof Error
|
|
1440
|
+
? `${error.name} ${error.message}`
|
|
1441
|
+
: String((error as { message?: unknown } | null)?.message ?? error ?? '');
|
|
1442
|
+
if (errorText.includes('Failure_UnexpectedMessage')) {
|
|
1443
|
+
throw createDeviceNotSupportMethodError('deviceUnlock', this.getCurrentFirmwareType());
|
|
1444
|
+
}
|
|
1445
|
+
throw error;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
const status = await requestProtocolV2DeviceStatus({ commands: this.commands });
|
|
1449
|
+
return this.updateProtocolV2Status(status);
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1169
1452
|
const firmwareVersion = this.getCurrentFirmwareVersionString() ?? '0.0.0';
|
|
1170
1453
|
const versionRange = this.getCurrentMethodVersionRange(
|
|
1171
1454
|
type => this.supportUnlockVersionRange()[type]
|
|
@@ -1175,9 +1458,7 @@ export class Device extends EventEmitter {
|
|
|
1175
1458
|
this.features,
|
|
1176
1459
|
Enum_Capability.Capability_AttachToPin
|
|
1177
1460
|
);
|
|
1178
|
-
// Pro2 (Protocol V2) 版本线独立于 Pro 系列,固件从首个版本即支持 UnLockDevice
|
|
1179
1461
|
const supportUnlock =
|
|
1180
|
-
this.isProtocolV2() ||
|
|
1181
1462
|
supportAttachPinCapability ||
|
|
1182
1463
|
(versionRange &&
|
|
1183
1464
|
semver.valid(firmwareVersion) &&
|
|
@@ -1186,11 +1467,20 @@ export class Device extends EventEmitter {
|
|
|
1186
1467
|
if (supportUnlock) {
|
|
1187
1468
|
const res = await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
|
|
1188
1469
|
if (this.features) {
|
|
1189
|
-
this.
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1470
|
+
this.updateState(
|
|
1471
|
+
{
|
|
1472
|
+
status: {
|
|
1473
|
+
unlocked: res.message.unlocked == null ? null : res.message.unlocked,
|
|
1474
|
+
unlockedAttachPin:
|
|
1475
|
+
res.message.unlocked_attach_pin == null ? null : res.message.unlocked_attach_pin,
|
|
1476
|
+
passphraseProtection:
|
|
1477
|
+
res.message.passphrase_protection == null
|
|
1478
|
+
? null
|
|
1479
|
+
: res.message.passphrase_protection,
|
|
1480
|
+
},
|
|
1481
|
+
},
|
|
1482
|
+
'unlock'
|
|
1483
|
+
);
|
|
1194
1484
|
|
|
1195
1485
|
return Promise.resolve(this.features);
|
|
1196
1486
|
}
|
|
@@ -1199,14 +1489,6 @@ export class Device extends EventEmitter {
|
|
|
1199
1489
|
return Promise.resolve(features);
|
|
1200
1490
|
}
|
|
1201
1491
|
|
|
1202
|
-
// legacy 解锁探测仅适用于 Protocol V1 老固件;V2 固件必然支持 UnLockDevice
|
|
1203
|
-
if (this.isProtocolV2()) {
|
|
1204
|
-
throw ERRORS.TypedError(
|
|
1205
|
-
HardwareErrorCode.RuntimeError,
|
|
1206
|
-
'unlock device error: device firmware does not support UnLockDevice'
|
|
1207
|
-
);
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
1492
|
const { type } = await this.commands.typedCall('GetAddress', 'Address', {
|
|
1211
1493
|
address_n: [toHardened(44), toHardened(1), toHardened(0), 0, 0],
|
|
1212
1494
|
coin_name: 'Testnet',
|
|
@@ -1229,21 +1511,27 @@ export class Device extends EventEmitter {
|
|
|
1229
1511
|
) {
|
|
1230
1512
|
if (this.isUnacquired()) return false;
|
|
1231
1513
|
|
|
1514
|
+
const expectedPassphraseState = useEmptyPassphrase ? undefined : passphraseState;
|
|
1232
1515
|
const { passphraseState: newPassphraseState, unlockedAttachPin } =
|
|
1233
1516
|
await getPassphraseStateWithRefreshDeviceInfo(this, {
|
|
1234
|
-
expectPassphraseState:
|
|
1517
|
+
expectPassphraseState: expectedPassphraseState,
|
|
1235
1518
|
onlyMainPin: useEmptyPassphrase,
|
|
1236
1519
|
});
|
|
1237
1520
|
|
|
1238
1521
|
// Main wallet and unlock Attach Pin, throw safe error
|
|
1239
1522
|
const mainWalletUseAttachPin = unlockedAttachPin && useEmptyPassphrase;
|
|
1240
1523
|
const useErrorAttachPin =
|
|
1241
|
-
unlockedAttachPin &&
|
|
1242
|
-
|
|
1524
|
+
unlockedAttachPin &&
|
|
1525
|
+
expectedPassphraseState &&
|
|
1526
|
+
expectedPassphraseState !== newPassphraseState;
|
|
1527
|
+
const passphraseStateMismatch =
|
|
1528
|
+
!!expectedPassphraseState && expectedPassphraseState !== newPassphraseState;
|
|
1243
1529
|
|
|
1244
1530
|
Log.debug('Check passphrase state safety: ', {
|
|
1245
|
-
|
|
1246
|
-
newPassphraseState,
|
|
1531
|
+
hasExpectedPassphraseState: Boolean(expectedPassphraseState),
|
|
1532
|
+
hasNewPassphraseState: Boolean(newPassphraseState),
|
|
1533
|
+
passphraseStateMatches:
|
|
1534
|
+
Boolean(expectedPassphraseState) && expectedPassphraseState === newPassphraseState,
|
|
1247
1535
|
unlockedAttachPin,
|
|
1248
1536
|
useEmptyPassphrase,
|
|
1249
1537
|
});
|