@onekeyfe/hd-core 1.2.0-alpha.16 → 1.2.0-alpha.160
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 +390 -0
- package/__tests__/DeviceCommands.test.ts +586 -9
- package/__tests__/DeviceEventRegistration.test.ts +9 -0
- package/__tests__/base64Data.test.ts +69 -0
- package/__tests__/chain-params-onekey-compatibility.test.ts +229 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +878 -0
- package/__tests__/check-firmware-release-protocol-v2.test.ts +270 -0
- package/__tests__/connectSettings.test.ts +45 -5
- package/__tests__/core-dispose.test.ts +34 -0
- package/__tests__/core-error-output.test.ts +39 -0
- package/__tests__/core-initialization.test.ts +23 -0
- package/__tests__/device-connector-protocol.test.ts +102 -0
- package/__tests__/device-features-state.test.ts +78 -0
- package/__tests__/device-identity.test.ts +52 -0
- package/__tests__/device-initialize-timeout.test.ts +56 -0
- package/__tests__/device-lifecycle-events.test.ts +754 -0
- package/__tests__/device-pool-state.test.ts +191 -0
- package/__tests__/device-settings.test.ts +665 -0
- package/__tests__/device-state-contract.test.ts +28 -0
- package/__tests__/device-state-events.test.ts +286 -0
- package/__tests__/device-state-mapper.test.ts +344 -0
- package/__tests__/device-state-projector.test.ts +114 -0
- package/__tests__/device-state-store.test.ts +109 -0
- package/__tests__/device-utils.test.ts +168 -0
- package/__tests__/device-wallet-session-store.test.ts +474 -1
- package/__tests__/deviceFeaturesUtils.test.ts +39 -0
- package/__tests__/devicePoolBootloaderPath.test.ts +64 -0
- package/__tests__/deviceSettings.test.ts +117 -0
- package/__tests__/deviceUploadNft.test.ts +348 -0
- package/__tests__/evmLedgerLegacySafety.test.ts +12 -6
- package/__tests__/evmSignTransaction.test.ts +69 -0
- package/__tests__/evmSignTypedData.test.ts +80 -0
- package/__tests__/filesystemValidation.test.ts +53 -0
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +175 -0
- package/__tests__/firmware-update/device-update-bootloader.test.ts +109 -0
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +171 -0
- package/__tests__/firmware-update/firmware-host-binding.test.ts +79 -0
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +27 -0
- package/__tests__/firmware-update/firmware-prepared-host-digest.test.ts +583 -0
- package/__tests__/firmware-update/firmware-prepared-resource-archive.test.ts +171 -0
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +438 -0
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +13 -0
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +474 -0
- package/__tests__/firmware-update/firmware-update-plan.test.ts +819 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +297 -0
- package/__tests__/firmware-update/firmware-update-prepared-resource-executors.test.ts +326 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +457 -0
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +237 -0
- package/__tests__/firmware-update/firmware-update-v4-install-poll.test.ts +166 -0
- package/__tests__/firmware-update/firmware-update-v4-parameters.test.ts +85 -0
- package/__tests__/firmware-update/firmware-upload-source.test.ts +70 -0
- package/__tests__/get-device-state.test.ts +617 -0
- package/__tests__/homescreen.test.ts +81 -0
- package/__tests__/kaspa-public-types.type-test.ts +16 -0
- package/__tests__/kaspa-use-tweak-pro2.test.ts +20 -0
- package/__tests__/kaspaSignTransaction.test.ts +578 -0
- package/__tests__/known-device-public-types.type-test.ts +3 -0
- package/__tests__/logBlockEvent.test.ts +140 -1
- package/__tests__/method-protocol-support.test.ts +144 -0
- package/__tests__/networkUtils.test.ts +406 -0
- package/__tests__/open-wallet-session-error-response.test.ts +43 -0
- package/__tests__/open-wallet-session.test.ts +1899 -0
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/pro2Wallpaper.test.ts +8 -19
- package/__tests__/protocol-binding.test.ts +89 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +105 -0
- package/__tests__/protocol-v2-ping.test.ts +28 -0
- package/__tests__/protocol-v2-resources.test.ts +364 -0
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +507 -0
- package/__tests__/protocol-v2.test.ts +7901 -2129
- package/__tests__/protocolV2FileWrite.test.ts +221 -3
- package/__tests__/protocolV2UiInteraction.test.ts +329 -0
- package/__tests__/public-device-state-api.test.ts +275 -0
- package/__tests__/public-pro2-api-boundary.test.ts +107 -0
- package/__tests__/refresh-device-state.test.ts +103 -0
- package/__tests__/request-context-logging.test.ts +16 -0
- package/__tests__/resourceBase64Boundary.test.ts +48 -0
- package/__tests__/search-devices.test.ts +192 -0
- package/__tests__/ton-sign-message.test.ts +84 -0
- package/__tests__/tron-sign-message-init.test.ts +74 -0
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/__tests__/uiPromiseRegistry.test.ts +115 -0
- package/dist/api/BaseMethod.d.ts +14 -2
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +25 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBLEFirmwareRelease.d.ts +3 -2
- package/dist/api/CheckBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts +2 -1
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts +3 -2
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CipherKeyValue.d.ts +1 -0
- package/dist/api/CipherKeyValue.d.ts.map +1 -1
- package/dist/api/ClearSessionCache.d.ts.map +1 -1
- package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/api/DirList.d.ts +1 -0
- package/dist/api/DirList.d.ts.map +1 -1
- package/dist/api/DirMake.d.ts +1 -0
- package/dist/api/DirMake.d.ts.map +1 -1
- package/dist/api/DirRemove.d.ts +1 -0
- package/dist/api/DirRemove.d.ts.map +1 -1
- package/dist/api/FileDelete.d.ts +1 -0
- package/dist/api/FileDelete.d.ts.map +1 -1
- package/dist/api/FileRead.d.ts +1 -0
- 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/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +13 -2
- 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 +62 -14
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetDeviceState.d.ts +8 -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 -0
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts +8 -0
- package/dist/api/OpenWalletSession.d.ts.map +1 -0
- package/dist/api/PathInfo.d.ts +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 +1 -2
- package/dist/api/UploadPortfolio.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumGetAddress.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
- package/dist/api/algo/AlgoGetAddress.d.ts +1 -0
- package/dist/api/algo/AlgoGetAddress.d.ts.map +1 -1
- package/dist/api/algo/AlgoSignTransaction.d.ts +1 -0
- package/dist/api/algo/AlgoSignTransaction.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +1 -0
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/aptos/AptosGetAddress.d.ts +1 -0
- package/dist/api/aptos/AptosGetAddress.d.ts.map +1 -1
- package/dist/api/aptos/AptosGetPublicKey.d.ts +1 -0
- package/dist/api/aptos/AptosGetPublicKey.d.ts.map +1 -1
- package/dist/api/aptos/AptosSignInMessage.d.ts +1 -0
- package/dist/api/aptos/AptosSignInMessage.d.ts.map +1 -1
- package/dist/api/aptos/AptosSignMessage.d.ts +1 -0
- package/dist/api/aptos/AptosSignMessage.d.ts.map +1 -1
- package/dist/api/aptos/AptosSignTransaction.d.ts +1 -0
- package/dist/api/aptos/AptosSignTransaction.d.ts.map +1 -1
- package/dist/api/benfen/BenfenGetAddress.d.ts.map +1 -1
- package/dist/api/benfen/BenfenGetPublicKey.d.ts.map +1 -1
- package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
- package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
- package/dist/api/btc/BTCGetAddress.d.ts +1 -0
- package/dist/api/btc/BTCGetAddress.d.ts.map +1 -1
- package/dist/api/btc/BTCGetPublicKey.d.ts +1 -0
- package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
- package/dist/api/btc/BTCSignMessage.d.ts +1 -0
- package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
- package/dist/api/btc/BTCSignPsbt.d.ts +1 -0
- package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
- package/dist/api/btc/BTCSignTransaction.d.ts +1 -0
- package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
- package/dist/api/btc/BTCVerifyMessage.d.ts +1 -0
- package/dist/api/btc/BTCVerifyMessage.d.ts.map +1 -1
- package/dist/api/btc/helpers/versionLimit.d.ts +2 -0
- package/dist/api/btc/helpers/versionLimit.d.ts.map +1 -1
- package/dist/api/cardano/CardanoGetAddress.d.ts +1 -0
- package/dist/api/cardano/CardanoGetAddress.d.ts.map +1 -1
- package/dist/api/cardano/CardanoGetPublicKey.d.ts +1 -0
- package/dist/api/cardano/CardanoGetPublicKey.d.ts.map +1 -1
- package/dist/api/cardano/CardanoSignMessage.d.ts +1 -0
- package/dist/api/cardano/CardanoSignMessage.d.ts.map +1 -1
- package/dist/api/cardano/CardanoSignTransaction.d.ts +1 -0
- package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxGetAddress.d.ts +2 -0
- package/dist/api/conflux/ConfluxGetAddress.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignMessage.d.ts +2 -0
- package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts +2 -0
- package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignTransaction.d.ts +2 -0
- package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
- package/dist/api/cosmos/CosmosGetAddress.d.ts +1 -0
- package/dist/api/cosmos/CosmosGetAddress.d.ts.map +1 -1
- package/dist/api/cosmos/CosmosGetPublicKey.d.ts +1 -0
- package/dist/api/cosmos/CosmosGetPublicKey.d.ts.map +1 -1
- package/dist/api/cosmos/CosmosSignTransaction.d.ts +1 -0
- package/dist/api/cosmos/CosmosSignTransaction.d.ts.map +1 -1
- package/dist/api/device/DeviceCancel.d.ts +1 -0
- package/dist/api/device/DeviceCancel.d.ts.map +1 -1
- package/dist/api/device/DeviceChangePin.d.ts +1 -0
- 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 +1 -0
- package/dist/api/device/DeviceLock.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBoardloader.d.ts +1 -0
- package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBootloader.d.ts +1 -0
- package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceSettings.d.ts +1 -0
- package/dist/api/device/DeviceSettings.d.ts.map +1 -1
- package/dist/api/device/DeviceSupportFeatures.d.ts +1 -0
- package/dist/api/device/DeviceSupportFeatures.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +3 -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/device/DeviceVerify.d.ts +1 -0
- package/dist/api/device/DeviceVerify.d.ts.map +1 -1
- package/dist/api/device/DeviceWipe.d.ts +1 -0
- package/dist/api/device/DeviceWipe.d.ts.map +1 -1
- package/dist/api/device/PreInitialize.d.ts +1 -0
- package/dist/api/device/PreInitialize.d.ts.map +1 -1
- package/dist/api/dynex/DnxGetAddress.d.ts.map +1 -1
- package/dist/api/dynex/DnxSignTransaction.d.ts.map +1 -1
- package/dist/api/evm/EVMGetAddress.d.ts +1 -0
- package/dist/api/evm/EVMGetAddress.d.ts.map +1 -1
- package/dist/api/evm/EVMGetPublicKey.d.ts +1 -0
- package/dist/api/evm/EVMGetPublicKey.d.ts.map +1 -1
- package/dist/api/evm/EVMSignMessage.d.ts +1 -0
- package/dist/api/evm/EVMSignMessage.d.ts.map +1 -1
- package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTransaction.d.ts +1 -0
- package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts +1 -0
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/evm/EVMVerifyMessage.d.ts +1 -0
- package/dist/api/evm/EVMVerifyMessage.d.ts.map +1 -1
- package/dist/api/evm/protocol.d.ts +3 -0
- package/dist/api/evm/protocol.d.ts.map +1 -0
- package/dist/api/filecoin/FilecoinGetAddress.d.ts +1 -0
- package/dist/api/filecoin/FilecoinGetAddress.d.ts.map +1 -1
- package/dist/api/filecoin/FilecoinSignTransaction.d.ts +1 -0
- package/dist/api/filecoin/FilecoinSignTransaction.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +29 -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/FirmwarePreparedResourceArchive.d.ts +11 -0
- package/dist/api/firmware/FirmwarePreparedResourceArchive.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +12 -3
- 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 +57 -0
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +38 -0
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -0
- package/dist/api/firmware/getBinary.d.ts +15 -4
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/protocolV2Release.d.ts +33 -0
- package/dist/api/firmware/protocolV2Release.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/base64Data.d.ts +16 -0
- package/dist/api/helpers/base64Data.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 +11 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +5 -29
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaGetAddress.d.ts +4 -0
- package/dist/api/kaspa/KaspaGetAddress.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts +9 -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/lightning/LnurlAuth.d.ts +0 -4
- package/dist/api/lightning/LnurlAuth.d.ts.map +1 -1
- package/dist/api/near/NearGetAddress.d.ts +1 -0
- package/dist/api/near/NearGetAddress.d.ts.map +1 -1
- package/dist/api/near/NearSignTransaction.d.ts +1 -0
- package/dist/api/near/NearSignTransaction.d.ts.map +1 -1
- package/dist/api/nem/NEMGetAddress.d.ts +1 -0
- package/dist/api/nem/NEMGetAddress.d.ts.map +1 -1
- package/dist/api/nem/NEMSignTransaction.d.ts +1 -0
- package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -1
- package/dist/api/neo/NeoGetAddress.d.ts.map +1 -1
- package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
- package/dist/api/nervos/NervosGetAddress.d.ts.map +1 -1
- package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
- package/dist/api/nexa/NexaGetAddress.d.ts.map +1 -1
- package/dist/api/nexa/NexaSignTransaction.d.ts +1 -0
- package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
- package/dist/api/nostr/NostrDecryptMessage.d.ts +1 -0
- package/dist/api/nostr/NostrDecryptMessage.d.ts.map +1 -1
- package/dist/api/nostr/NostrEncryptMessage.d.ts +1 -0
- package/dist/api/nostr/NostrEncryptMessage.d.ts.map +1 -1
- package/dist/api/nostr/NostrGetPublicKey.d.ts +1 -0
- package/dist/api/nostr/NostrGetPublicKey.d.ts.map +1 -1
- package/dist/api/nostr/NostrSignEvent.d.ts +1 -0
- package/dist/api/nostr/NostrSignEvent.d.ts.map +1 -1
- package/dist/api/nostr/NostrSignSchnorr.d.ts +1 -0
- package/dist/api/nostr/NostrSignSchnorr.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotGetAddress.d.ts +2 -1
- package/dist/api/polkadot/PolkadotGetAddress.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotSignTransaction.d.ts +1 -0
- package/dist/api/polkadot/PolkadotSignTransaction.d.ts.map +1 -1
- package/dist/api/polkadot/networks.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +4 -1
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +2 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts +2 -2
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceReboot.d.ts +2 -1
- package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +30 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +3 -3
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/api/protocol-v2/FilesystemFormat.d.ts +1 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts +1 -0
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -1
- package/dist/api/protocol-v2/Ping.d.ts +3 -0
- package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/scdo/ScdoGetAddress.d.ts.map +1 -1
- package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
- package/dist/api/scdo/ScdoSignTransaction.d.ts.map +1 -1
- package/dist/api/solana/SolGetAddress.d.ts +1 -0
- package/dist/api/solana/SolGetAddress.d.ts.map +1 -1
- package/dist/api/solana/SolSignMessage.d.ts +2 -1
- package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts +2 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
- package/dist/api/solana/SolSignTransaction.d.ts +3 -2
- package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinGetAddress.d.ts +1 -0
- package/dist/api/starcoin/StarcoinGetAddress.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinGetPublicKey.d.ts +1 -0
- package/dist/api/starcoin/StarcoinGetPublicKey.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinSignMessage.d.ts +1 -0
- package/dist/api/starcoin/StarcoinSignMessage.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinSignTransaction.d.ts +1 -0
- package/dist/api/starcoin/StarcoinSignTransaction.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinVerifyMessage.d.ts +1 -0
- package/dist/api/starcoin/StarcoinVerifyMessage.d.ts.map +1 -1
- package/dist/api/stellar/StellarGetAddress.d.ts +1 -2
- package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +2 -3
- package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
- package/dist/api/sui/SuiGetAddress.d.ts +2 -1
- package/dist/api/sui/SuiGetAddress.d.ts.map +1 -1
- package/dist/api/sui/SuiGetPublicKey.d.ts +2 -1
- package/dist/api/sui/SuiGetPublicKey.d.ts.map +1 -1
- package/dist/api/sui/SuiSignMessage.d.ts +2 -1
- package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
- package/dist/api/sui/SuiSignTransaction.d.ts +2 -1
- package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
- package/dist/api/ton/TonGetAddress.d.ts +2 -1
- package/dist/api/ton/TonGetAddress.d.ts.map +1 -1
- package/dist/api/ton/TonSignData.d.ts +1 -0
- package/dist/api/ton/TonSignData.d.ts.map +1 -1
- package/dist/api/ton/TonSignMessage.d.ts +2 -1
- package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
- package/dist/api/ton/TonSignProof.d.ts +2 -1
- package/dist/api/ton/TonSignProof.d.ts.map +1 -1
- package/dist/api/tron/TronGetAddress.d.ts +1 -0
- package/dist/api/tron/TronGetAddress.d.ts.map +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +6 -1
- package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
- package/dist/api/tron/TronSignTransaction.d.ts +2 -1
- package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
- package/dist/api/utils.d.ts +4 -1
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/api/xrp/XrpGetAddress.d.ts +1 -0
- package/dist/api/xrp/XrpGetAddress.d.ts.map +1 -1
- package/dist/api/xrp/XrpSignTransaction.d.ts +1 -0
- package/dist/api/xrp/XrpSignTransaction.d.ts.map +1 -1
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/core/RequestQueue.d.ts +0 -2
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/deviceEventRegistration.d.ts +3 -0
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts +8 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/uiPromiseRegistry.d.ts +6 -0
- package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
- package/dist/data-manager/DataManager.d.ts +14 -5
- 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 +84 -16
- 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/DeviceConnector.d.ts +4 -3
- package/dist/device/DeviceConnector.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 +6 -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 +13 -1
- package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -1
- 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 +8 -2
- 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/deviceProfile/protocolV2DeviceIdentity.d.ts +7 -0
- package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -0
- package/dist/events/call.d.ts +0 -7
- package/dist/events/call.d.ts.map +1 -1
- package/dist/events/core.d.ts +2 -2
- package/dist/events/core.d.ts.map +1 -1
- package/dist/events/device.d.ts +16 -2
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/iframe.d.ts +0 -1
- package/dist/events/iframe.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts +2 -0
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-promise.d.ts +4 -2
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +50 -4
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +10 -2
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +1743 -830
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11463 -4629
- package/dist/inject.d.ts +7 -3
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts +1 -2
- package/dist/lowLevelInject.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 +33 -22
- 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/index.d.ts +2 -2
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/resources.d.ts +17 -0
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts +17 -0
- package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +42 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +2 -0
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +18 -4
- 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 +48 -9
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBLEFirmwareRelease.d.ts +2 -13
- package/dist/types/api/checkBLEFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkBootloaderRelease.d.ts +2 -6
- package/dist/types/api/checkBootloaderRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareRelease.d.ts +2 -13
- package/dist/types/api/checkFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/checkFirmwareTypeAvailable.d.ts +2 -2
- package/dist/types/api/checkFirmwareTypeAvailable.d.ts.map +1 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/types/api/deviceSettings.d.ts +11 -2
- package/dist/types/api/deviceSettings.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +6 -2
- 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 +8 -3
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +67 -5
- 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/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.map +1 -1
- package/dist/types/api/index.d.ts +25 -35
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/kaspaSignTransaction.d.ts +42 -4
- package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
- package/dist/types/api/openWalletSession.d.ts +35 -0
- package/dist/types/api/openWalletSession.d.ts.map +1 -0
- package/dist/types/api/protocolV2.d.ts +11 -93
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/sessionCache.d.ts +4 -1
- package/dist/types/api/sessionCache.d.ts.map +1 -1
- package/dist/types/device.d.ts +139 -8
- 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 +31 -16
- 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 +14 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -0
- package/dist/utils/deviceFeaturesUtils.d.ts +10 -1
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts +9 -9
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/deviceSettings.d.ts +39 -7
- package/dist/utils/deviceSettings.d.ts.map +1 -1
- package/dist/utils/deviceVersionUtils.d.ts +7 -5
- package/dist/utils/deviceVersionUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +4 -0
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/networkUtils.d.ts +10 -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/pro2Nft.d.ts +38 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -0
- package/dist/utils/pro2Wallpaper.d.ts +10 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/dist/utils/tracing.d.ts.map +1 -1
- package/dist/utils/uiProgressThrottle.d.ts +3 -0
- package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
- package/package.json +6 -4
- package/src/api/BaseMethod.ts +45 -23
- package/src/api/CheckAllFirmwareRelease.ts +440 -4
- package/src/api/CheckBLEFirmwareRelease.ts +37 -5
- package/src/api/CheckBootloaderRelease.ts +37 -5
- package/src/api/CheckFirmwareRelease.ts +36 -9
- package/src/api/CipherKeyValue.ts +4 -0
- package/src/api/ClearSessionCache.ts +4 -0
- package/src/api/DetectDeviceConnectProtocol.ts +18 -0
- package/src/api/DirList.ts +9 -4
- package/src/api/DirMake.ts +7 -4
- package/src/api/DirRemove.ts +7 -4
- package/src/api/FileDelete.ts +7 -4
- package/src/api/FileRead.ts +13 -7
- package/src/api/FileWrite.ts +7 -4
- package/src/api/FirmwareUpdate.ts +30 -15
- package/src/api/FirmwareUpdateV2.ts +535 -169
- package/src/api/FirmwareUpdateV3.ts +350 -91
- package/src/api/FirmwareUpdateV4.ts +2036 -744
- package/src/api/GetDeviceState.ts +59 -0
- package/src/api/GetFeatures.ts +6 -4
- package/src/api/GetOnekeyFeatures.ts +1 -75
- package/src/api/GetPassphraseState.ts +36 -12
- package/src/api/OpenWalletSession.ts +268 -0
- package/src/api/PathInfo.ts +9 -4
- package/src/api/PromptWebDeviceAccess.ts +3 -8
- package/src/api/SearchDevices.ts +35 -5
- package/src/api/UploadPortfolio.ts +30 -4
- package/src/api/alephium/AlephiumGetAddress.ts +0 -4
- package/src/api/alephium/AlephiumSignMessage.ts +0 -4
- package/src/api/alephium/AlephiumSignTransaction.ts +2 -6
- package/src/api/algo/AlgoGetAddress.ts +4 -0
- package/src/api/algo/AlgoSignTransaction.ts +4 -0
- package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +45 -32
- package/src/api/aptos/AptosGetAddress.ts +4 -0
- package/src/api/aptos/AptosGetPublicKey.ts +4 -0
- package/src/api/aptos/AptosSignInMessage.ts +4 -0
- package/src/api/aptos/AptosSignMessage.ts +4 -0
- package/src/api/aptos/AptosSignTransaction.ts +4 -0
- package/src/api/benfen/BenfenGetAddress.ts +11 -7
- package/src/api/benfen/BenfenGetPublicKey.ts +0 -4
- package/src/api/benfen/BenfenSignMessage.ts +0 -4
- package/src/api/benfen/BenfenSignTransaction.ts +0 -4
- package/src/api/btc/BTCGetAddress.ts +8 -1
- package/src/api/btc/BTCGetPublicKey.ts +9 -2
- package/src/api/btc/BTCSignMessage.ts +8 -1
- package/src/api/btc/BTCSignPsbt.ts +4 -0
- package/src/api/btc/BTCSignTransaction.ts +8 -1
- package/src/api/btc/BTCVerifyMessage.ts +8 -1
- package/src/api/btc/helpers/versionLimit.ts +7 -4
- package/src/api/cardano/CardanoGetAddress.ts +4 -0
- package/src/api/cardano/CardanoGetPublicKey.ts +4 -0
- package/src/api/cardano/CardanoSignMessage.ts +4 -0
- package/src/api/cardano/CardanoSignTransaction.ts +4 -0
- package/src/api/conflux/ConfluxGetAddress.ts +6 -0
- package/src/api/conflux/ConfluxSignMessage.ts +6 -0
- package/src/api/conflux/ConfluxSignMessageCIP23.ts +6 -0
- package/src/api/conflux/ConfluxSignTransaction.ts +8 -5
- package/src/api/cosmos/CosmosGetAddress.ts +4 -0
- package/src/api/cosmos/CosmosGetPublicKey.ts +4 -0
- package/src/api/cosmos/CosmosSignTransaction.ts +4 -0
- package/src/api/device/DeviceCancel.ts +5 -0
- package/src/api/device/DeviceChangePin.ts +31 -0
- package/src/api/device/DeviceFullyUploadResource.ts +4 -5
- package/src/api/device/DeviceLock.ts +5 -0
- package/src/api/device/DeviceRebootToBoardloader.ts +8 -1
- package/src/api/device/DeviceRebootToBootloader.ts +8 -1
- package/src/api/device/DeviceSettings.ts +211 -3
- package/src/api/device/DeviceSupportFeatures.ts +4 -0
- package/src/api/device/DeviceUnlock.ts +21 -3
- package/src/api/device/DeviceUpdateBootloader.ts +152 -8
- package/src/api/device/DeviceVerify.ts +25 -0
- package/src/api/device/DeviceWipe.ts +28 -0
- package/src/api/device/PreInitialize.ts +4 -0
- package/src/api/dynex/DnxGetAddress.ts +0 -6
- package/src/api/dynex/DnxSignTransaction.ts +0 -6
- package/src/api/evm/EVMGetAddress.ts +6 -2
- package/src/api/evm/EVMGetPublicKey.ts +6 -2
- package/src/api/evm/EVMSignMessage.ts +6 -2
- package/src/api/evm/EVMSignMessageEIP712.ts +1 -11
- package/src/api/evm/EVMSignTransaction.ts +6 -2
- package/src/api/evm/EVMSignTypedData.ts +42 -50
- package/src/api/evm/EVMVerifyMessage.ts +6 -2
- 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/evm/protocol.ts +6 -0
- package/src/api/filecoin/FilecoinGetAddress.ts +4 -0
- package/src/api/filecoin/FilecoinSignTransaction.ts +4 -0
- package/src/api/firmware/FirmwareArtifactSource.ts +305 -0
- package/src/api/firmware/FirmwareHostBinding.ts +123 -0
- package/src/api/firmware/FirmwarePreparationError.ts +12 -0
- package/src/api/firmware/FirmwarePreparedResourceArchive.ts +196 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +214 -77
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +9 -0
- package/src/api/firmware/FirmwareUpdatePlan.ts +905 -0
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +490 -0
- package/src/api/firmware/getBinary.ts +8 -3
- package/src/api/firmware/protocolV2Release.ts +173 -0
- package/src/api/firmware/updateBootloader.ts +19 -4
- package/src/api/firmware/uploadFirmware.ts +157 -26
- package/src/api/helpers/base64Data.ts +85 -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 +266 -42
- package/src/api/index.ts +6 -30
- package/src/api/kaspa/KaspaGetAddress.ts +7 -0
- package/src/api/kaspa/KaspaSignTransaction.ts +369 -29
- package/src/api/kaspa/helpers/TransferSerialize.ts +17 -7
- package/src/api/lightning/LnurlAuth.ts +0 -4
- package/src/api/near/NearGetAddress.ts +4 -0
- package/src/api/near/NearSignTransaction.ts +4 -0
- package/src/api/nem/NEMGetAddress.ts +4 -0
- package/src/api/nem/NEMSignTransaction.ts +4 -0
- package/src/api/neo/NeoGetAddress.ts +0 -4
- package/src/api/neo/NeoSignTransaction.ts +0 -4
- package/src/api/nervos/NervosGetAddress.ts +0 -4
- package/src/api/nervos/NervosSignTransaction.ts +2 -6
- package/src/api/nexa/NexaGetAddress.ts +0 -4
- package/src/api/nexa/NexaSignTransaction.ts +3 -5
- package/src/api/nostr/NostrDecryptMessage.ts +4 -0
- package/src/api/nostr/NostrEncryptMessage.ts +4 -0
- package/src/api/nostr/NostrGetPublicKey.ts +4 -0
- package/src/api/nostr/NostrSignEvent.ts +4 -0
- package/src/api/nostr/NostrSignSchnorr.ts +4 -0
- package/src/api/polkadot/PolkadotGetAddress.ts +4 -0
- package/src/api/polkadot/PolkadotSignTransaction.ts +4 -0
- package/src/api/polkadot/networks.ts +3 -3
- package/src/api/protocol-v2/DeviceFactoryInfoGet.ts +5 -2
- package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +6 -3
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +13 -32
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +10 -6
- package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +6 -3
- package/src/api/protocol-v2/DeviceInfoGet.ts +11 -18
- package/src/api/protocol-v2/DeviceReboot.ts +12 -3
- package/src/api/protocol-v2/DeviceStatusGet.ts +6 -1
- package/src/api/protocol-v2/DeviceUploadNft.ts +249 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +59 -21
- package/src/api/protocol-v2/FilesystemFormat.ts +5 -2
- package/src/api/protocol-v2/FilesystemPermissionFix.ts +5 -2
- package/src/api/protocol-v2/Ping.ts +37 -3
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +8 -3
- package/src/api/protocol-v2/helpers.ts +1 -1
- package/src/api/scdo/ScdoGetAddress.ts +0 -4
- package/src/api/scdo/ScdoSignMessage.ts +0 -4
- package/src/api/scdo/ScdoSignTransaction.ts +0 -4
- package/src/api/solana/SolGetAddress.ts +4 -0
- package/src/api/solana/SolSignMessage.ts +5 -1
- package/src/api/solana/SolSignOffchainMessage.ts +5 -1
- package/src/api/solana/SolSignTransaction.ts +6 -2
- package/src/api/starcoin/StarcoinGetAddress.ts +4 -0
- package/src/api/starcoin/StarcoinGetPublicKey.ts +4 -0
- package/src/api/starcoin/StarcoinSignMessage.ts +4 -0
- package/src/api/starcoin/StarcoinSignTransaction.ts +4 -0
- package/src/api/starcoin/StarcoinVerifyMessage.ts +4 -0
- package/src/api/stellar/StellarGetAddress.ts +1 -10
- package/src/api/stellar/StellarSignTransaction.ts +1 -14
- package/src/api/sui/SuiGetAddress.ts +5 -1
- package/src/api/sui/SuiGetPublicKey.ts +5 -1
- package/src/api/sui/SuiSignMessage.ts +5 -1
- package/src/api/sui/SuiSignTransaction.ts +5 -1
- package/src/api/ton/TonGetAddress.ts +5 -1
- package/src/api/ton/TonSignData.ts +5 -1
- package/src/api/ton/TonSignMessage.ts +10 -4
- package/src/api/ton/TonSignProof.ts +5 -1
- package/src/api/tron/TronGetAddress.ts +4 -0
- package/src/api/tron/TronSignMessage.ts +19 -8
- package/src/api/tron/TronSignTransaction.ts +5 -1
- package/src/api/utils.ts +32 -3
- package/src/api/xrp/XrpGetAddress.ts +4 -0
- package/src/api/xrp/XrpSignTransaction.ts +5 -1
- package/src/constants/index.ts +1 -4
- package/src/core/RequestQueue.ts +0 -18
- package/src/core/deviceEventRegistration.ts +6 -0
- package/src/core/index.ts +512 -195
- package/src/core/uiPromiseRegistry.ts +63 -0
- package/src/data/messages/messages-protocol-v2.json +523 -449
- package/src/data/messages/messages.json +286 -1
- package/src/data-manager/DataManager.ts +162 -44
- package/src/data-manager/TransportManager.ts +10 -2
- package/src/data-manager/connectSettings.ts +11 -0
- package/src/device/Device.ts +1021 -267
- package/src/device/DeviceCommands.ts +204 -162
- package/src/device/DeviceConnector.ts +54 -21
- package/src/device/DeviceFeaturesState.ts +25 -0
- package/src/device/DevicePool.ts +108 -23
- package/src/device/DeviceStateMapper.ts +422 -0
- package/src/device/DeviceStateProjector.ts +152 -0
- package/src/device/DeviceStateStore.ts +232 -0
- package/src/device/DeviceWalletSessionStore.ts +72 -6
- package/src/device/cloneDeviceState.ts +39 -0
- package/src/device/deviceIdentity.ts +18 -0
- package/src/deviceProfile/buildDeviceFeatures.ts +215 -192
- package/src/deviceProfile/index.ts +0 -1
- package/src/deviceProfile/protocolV2DeviceIdentity.ts +35 -0
- package/src/events/call.ts +0 -6
- package/src/events/core.ts +0 -2
- package/src/events/device.ts +22 -1
- package/src/events/iframe.ts +0 -1
- package/src/events/logBlockEvent.ts +93 -2
- package/src/events/ui-promise.ts +4 -2
- package/src/events/ui-request.ts +61 -4
- package/src/events/ui-response.ts +12 -2
- package/src/index.ts +7 -4
- package/src/inject.ts +89 -55
- package/src/lowLevelInject.ts +11 -7
- package/src/protocols/protocol-v2/deviceSession.ts +24 -0
- package/src/protocols/protocol-v2/features.ts +118 -52
- package/src/protocols/protocol-v2/firmware.ts +3 -1
- package/src/protocols/protocol-v2/index.ts +9 -3
- package/src/protocols/protocol-v2/resources.ts +165 -0
- package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +65 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +250 -0
- package/src/protocols/protocol-v2/unlockPolicy.ts +1 -0
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +136 -0
- package/src/protocols/protocol-v2/walletSession.ts +417 -61
- package/src/topLevelInject.ts +11 -6
- package/src/types/api/checkAllFirmwareRelease.ts +72 -9
- package/src/types/api/checkBLEFirmwareRelease.ts +4 -13
- package/src/types/api/checkBootloaderRelease.ts +2 -6
- package/src/types/api/checkFirmwareRelease.ts +2 -13
- package/src/types/api/checkFirmwareTypeAvailable.ts +2 -2
- package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
- package/src/types/api/deviceSettings.ts +26 -2
- package/src/types/api/deviceUnlock.ts +13 -2
- package/src/types/api/deviceUpdateBootloader.ts +7 -0
- package/src/types/api/export.ts +33 -1
- package/src/types/api/firmwareUpdate.ts +85 -11
- 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/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 +7 -0
- package/src/types/api/index.ts +43 -73
- package/src/types/api/kaspaSignTransaction.ts +60 -4
- package/src/types/api/openWalletSession.ts +54 -0
- package/src/types/api/protocolV2.ts +23 -188
- package/src/types/api/sessionCache.ts +9 -4
- package/src/types/device.ts +211 -9
- package/src/types/params.ts +9 -2
- package/src/types/settings.ts +37 -25
- package/src/utils/assets.ts +4 -1
- package/src/utils/deviceFeaturesCompat.ts +196 -0
- package/src/utils/deviceFeaturesUtils.ts +42 -9
- package/src/utils/deviceInfoUtils.ts +37 -70
- package/src/utils/deviceSettings.ts +181 -39
- package/src/utils/deviceVersionUtils.ts +25 -44
- package/src/utils/findDefectiveBatchDevice.ts +3 -3
- package/src/utils/homescreen.ts +40 -0
- package/src/utils/index.ts +26 -7
- package/src/utils/networkUtils.ts +274 -16
- package/src/utils/pro2Nft.ts +165 -0
- package/src/utils/pro2Wallpaper.ts +44 -25
- package/src/utils/tracing.ts +3 -1
- package/src/utils/uiProgressThrottle.ts +63 -0
- package/tsconfig.type-tests.json +12 -0
- package/__tests__/RequestQueue.test.ts +0 -34
- package/dist/api/GetDeviceInfo.d.ts +0 -9
- package/dist/api/GetDeviceInfo.d.ts.map +0 -1
- package/dist/api/firmware/progressThrottle.d.ts +0 -3
- package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts +0 -6
- package/dist/api/protocol-v2/DeviceSessionGet.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceSettingsGet.d.ts +0 -6
- package/dist/api/protocol-v2/DeviceSettingsGet.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts +0 -16
- package/dist/api/protocol-v2/DeviceSettingsPageShow.d.ts.map +0 -1
- package/dist/api/protocol-v2/DeviceSettingsSet.d.ts +0 -12
- package/dist/api/protocol-v2/DeviceSettingsSet.d.ts.map +0 -1
- package/dist/deviceProfile/buildDeviceProfile.d.ts +0 -21
- package/dist/deviceProfile/buildDeviceProfile.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -9
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
- package/dist/types/api/getDeviceInfo.d.ts +0 -87
- package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
- package/src/api/GetDeviceInfo.ts +0 -145
- package/src/api/firmware/progressThrottle.ts +0 -44
- package/src/api/protocol-v2/DeviceSessionGet.ts +0 -15
- package/src/api/protocol-v2/DeviceSettingsGet.ts +0 -16
- package/src/api/protocol-v2/DeviceSettingsPageShow.ts +0 -59
- package/src/api/protocol-v2/DeviceSettingsSet.ts +0 -39
- package/src/deviceProfile/buildDeviceProfile.ts +0 -354
- package/src/protocols/protocol-v2/lockedError.ts +0 -10
- package/src/protocols/protocol-v2/unlockRetry.ts +0 -36
- package/src/types/api/getDeviceInfo.ts +0 -101
package/src/device/Device.ts
CHANGED
|
@@ -1,41 +1,46 @@
|
|
|
1
1
|
import EventEmitter from 'events';
|
|
2
2
|
import semver from 'semver';
|
|
3
|
-
import { Enum_Capability } from '@onekeyfe/hd-transport';
|
|
3
|
+
import { DeviceRebootType, DeviceSessionPinType, Enum_Capability } from '@onekeyfe/hd-transport';
|
|
4
4
|
import {
|
|
5
5
|
EDeviceType,
|
|
6
|
+
EFirmwareType,
|
|
6
7
|
ERRORS,
|
|
7
8
|
ERROR_CODES_REQUIRE_DISCONNECT,
|
|
8
9
|
ERROR_CODES_REQUIRE_RELEASE,
|
|
9
10
|
HardwareError,
|
|
10
11
|
HardwareErrorCode,
|
|
12
|
+
canonicalizePro2BleAdvertisementName,
|
|
11
13
|
createDeferred,
|
|
12
14
|
createDeviceNotSupportMethodError,
|
|
13
15
|
} from '@onekeyfe/hd-shared';
|
|
14
16
|
|
|
15
|
-
import {
|
|
16
|
-
LoggerNames,
|
|
17
|
-
getDeviceBLEFirmwareVersion,
|
|
18
|
-
getDeviceBleName,
|
|
19
|
-
getDeviceFirmwareVersion,
|
|
20
|
-
getDeviceLabel,
|
|
21
|
-
getDeviceType,
|
|
22
|
-
getDeviceUUID,
|
|
23
|
-
getFirmwareType,
|
|
24
|
-
getLogger,
|
|
25
|
-
} from '../utils';
|
|
17
|
+
import { LoggerNames, getLogger } from '../utils';
|
|
26
18
|
import {
|
|
27
19
|
fixFeaturesFirmwareVersion,
|
|
28
20
|
getPassphraseStateWithRefreshDeviceInfo,
|
|
29
|
-
supportInputPinOnSoftware,
|
|
30
|
-
supportModifyHomescreen,
|
|
31
21
|
} from '../utils/deviceFeaturesUtils';
|
|
22
|
+
import { parseDeviceVersion } from '../utils/deviceVersionUtils';
|
|
32
23
|
import { generateInstanceId } from '../utils/tracing';
|
|
33
24
|
// eslint-disable-next-line import/no-cycle
|
|
34
25
|
import { DeviceCommands } from './DeviceCommands';
|
|
26
|
+
import { mergeDeviceFeaturesPatch } from './DeviceFeaturesState';
|
|
27
|
+
import {
|
|
28
|
+
mapDeviceSettingsToState,
|
|
29
|
+
mapFeaturesToState,
|
|
30
|
+
mapProtocolV1OnekeyFeaturesToState,
|
|
31
|
+
mapProtocolV2DeviceInfoToState,
|
|
32
|
+
mapProtocolV2DeviceStatusToState,
|
|
33
|
+
} from './DeviceStateMapper';
|
|
34
|
+
import { projectFeatures } from './DeviceStateProjector';
|
|
35
|
+
import { DeviceStateStore, createPublicDeviceState } from './DeviceStateStore';
|
|
36
|
+
import { cloneDeviceState } from './cloneDeviceState';
|
|
35
37
|
import { deviceWalletSessionStore } from './DeviceWalletSessionStore';
|
|
36
38
|
import {
|
|
37
39
|
type DeviceFirmwareRange,
|
|
38
40
|
DeviceModelToTypes,
|
|
41
|
+
type DeviceStateEvent,
|
|
42
|
+
type DeviceStatePatch,
|
|
43
|
+
type DeviceStateUpdateSource,
|
|
39
44
|
DeviceTypeToModels,
|
|
40
45
|
type Device as DeviceTyped,
|
|
41
46
|
EOneKeyDeviceMode,
|
|
@@ -50,24 +55,37 @@ import { DEVICE, UI_REQUEST } from '../events';
|
|
|
50
55
|
import { DataManager } from '../data-manager';
|
|
51
56
|
import TransportManager from '../data-manager/TransportManager';
|
|
52
57
|
import { toHardened } from '../api/helpers/pathUtils';
|
|
53
|
-
import { existCapability } from '../utils/capabilitieUtils';
|
|
54
58
|
import {
|
|
55
|
-
|
|
59
|
+
PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE,
|
|
60
|
+
PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST,
|
|
61
|
+
PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST,
|
|
62
|
+
PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
|
|
63
|
+
type ProtocolV2RuntimeMode,
|
|
64
|
+
getProtocolV2RuntimeMode,
|
|
65
|
+
isLegacyProtocolV2ProtocolInfo,
|
|
56
66
|
requestProtocolV2DeviceInfo,
|
|
67
|
+
requestProtocolV2DeviceStatus,
|
|
68
|
+
requestProtocolV2ProtocolInfo,
|
|
69
|
+
supportsProtocolV2Message,
|
|
57
70
|
} from '../protocols/protocol-v2/features';
|
|
58
|
-
import { buildProtocolV1FeaturesPayload
|
|
71
|
+
import { buildProtocolV1FeaturesPayload } from '../deviceProfile';
|
|
72
|
+
import { resolveProtocolV2DeviceIdentity } from '../deviceProfile/protocolV2DeviceIdentity';
|
|
59
73
|
|
|
60
74
|
import type { PROTO } from '../constants';
|
|
75
|
+
import type { DeviceStateReadOptions } from '../types/api/getDeviceState';
|
|
61
76
|
import type {
|
|
62
77
|
DeviceButtonRequestPayload,
|
|
63
78
|
DeviceFeaturesPayload,
|
|
79
|
+
HardwareUiInteractionMeta,
|
|
64
80
|
PassphraseRequestPayload,
|
|
81
|
+
ProtocolV2UiEventMetadata,
|
|
65
82
|
} from '../events';
|
|
66
83
|
import type { PassphrasePromptResponse } from './DeviceCommands';
|
|
67
84
|
import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
|
|
68
85
|
import type {
|
|
69
86
|
OneKeyDeviceInfo as DeviceDescriptor,
|
|
70
87
|
DeviceStatus,
|
|
88
|
+
ProtocolInfo,
|
|
71
89
|
ProtocolV2DeviceInfo,
|
|
72
90
|
Success,
|
|
73
91
|
} from '@onekeyfe/hd-transport';
|
|
@@ -79,7 +97,15 @@ export type InitOptions = {
|
|
|
79
97
|
passphraseState?: string;
|
|
80
98
|
deriveCardano?: boolean;
|
|
81
99
|
connectProtocol?: HardwareConnectProtocol;
|
|
100
|
+
forceProtocolDetection?: boolean;
|
|
82
101
|
protocolV2DeviceInfoTimeoutMs?: number;
|
|
102
|
+
/** Refresh Protocol V2 runtime state before returning discovery results. */
|
|
103
|
+
refreshRuntimeState?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Protocol V1 Initialize response timeout override. Reboot-wait polling passes a
|
|
106
|
+
* short value so an unanswered probe settles before the next poll tick.
|
|
107
|
+
*/
|
|
108
|
+
timeoutMs?: number;
|
|
83
109
|
};
|
|
84
110
|
|
|
85
111
|
export type RunOptions = {
|
|
@@ -94,11 +120,35 @@ const parseRunOptions = (options?: RunOptions): RunOptions => {
|
|
|
94
120
|
|
|
95
121
|
const Log = getLogger(LoggerNames.Device);
|
|
96
122
|
|
|
123
|
+
const isProtocolV2DeviceStatusUnsupportedError = (error: unknown) => {
|
|
124
|
+
if (error instanceof HardwareError) {
|
|
125
|
+
if (error.errorCode === HardwareErrorCode.DeviceNotSupportMethod) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
if (error.params?.failureCode === 'Failure_UnexpectedMessage') {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const message =
|
|
134
|
+
error instanceof Error
|
|
135
|
+
? error.message
|
|
136
|
+
: String((error as { message?: unknown } | null)?.message ?? error ?? '');
|
|
137
|
+
return (
|
|
138
|
+
/^Failure_UnexpectedMessage(?:,|\b)/i.test(message) ||
|
|
139
|
+
/\b(?:unsupported message|handler not registered|message handler not found)\b/i.test(message)
|
|
140
|
+
);
|
|
141
|
+
};
|
|
142
|
+
|
|
97
143
|
export interface DeviceEvents {
|
|
98
144
|
[DEVICE.PIN]: [Device, PROTO.PinMatrixRequestType | undefined, (err: any, pin: string) => void];
|
|
99
|
-
[DEVICE.
|
|
145
|
+
[DEVICE.PIN_ON_DEVICE]: [Device, DeviceSessionPinType, ProtocolV2UiEventMetadata?];
|
|
146
|
+
[DEVICE.PIN_ON_DEVICE_COMPLETE]: [Device, HardwareUiInteractionMeta];
|
|
147
|
+
[DEVICE.PASSPHRASE_ON_DEVICE]: [Device, PassphraseRequestPayload?];
|
|
148
|
+
[DEVICE.ATTACH_PIN_ON_DEVICE]: [Device, PassphraseRequestPayload?];
|
|
100
149
|
[DEVICE.BUTTON]: [Device, DeviceButtonRequestPayload];
|
|
101
150
|
[DEVICE.FEATURES]: [Device, DeviceFeaturesPayload];
|
|
151
|
+
[DEVICE.STATE]: [Device, DeviceStateEvent];
|
|
102
152
|
[DEVICE.PASSPHRASE]: [
|
|
103
153
|
Device,
|
|
104
154
|
PassphraseRequestPayload,
|
|
@@ -128,7 +178,8 @@ export interface Device {
|
|
|
128
178
|
* This allows short-lived processes (e.g. CLI) to restore a previously
|
|
129
179
|
* obtained session, avoiding the need to re-enter passphrase on every
|
|
130
180
|
* invocation. The session must have been obtained from a prior
|
|
131
|
-
*
|
|
181
|
+
* wallet-session call on the same device. This compatibility hook is intended
|
|
182
|
+
* for a trusted CLI process restoring its own OS-keychain entry.
|
|
132
183
|
*
|
|
133
184
|
* @param deviceId - The device's device_id (from features)
|
|
134
185
|
* @param passphraseState - The passphrase state token
|
|
@@ -186,24 +237,66 @@ export class Device extends EventEmitter {
|
|
|
186
237
|
private deviceAcquired = false;
|
|
187
238
|
|
|
188
239
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
* Features 视图。Device 不再保存 profile,结构化 DeviceProfile 只作为
|
|
193
|
-
* getDeviceInfo() 的 API 返回值存在。
|
|
240
|
+
* Connection-attempt generation. interruptionFromUser() pins the current
|
|
241
|
+
* attempt so a late acquire cannot finish, while the next public connect
|
|
242
|
+
* increments this and is allowed to proceed.
|
|
194
243
|
*/
|
|
195
|
-
|
|
244
|
+
private connectionAttempt = 0;
|
|
196
245
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
246
|
+
private interruptedAttempt: number | null = null;
|
|
247
|
+
|
|
248
|
+
/** Canonical device-state cache; legacy Features is a compatibility projection. */
|
|
249
|
+
private stateStore = new DeviceStateStore();
|
|
250
|
+
|
|
251
|
+
/** Force the next initialization to reload DeviceInfo after reconnect or reboot. */
|
|
252
|
+
private protocolV2StateNeedsReload = false;
|
|
253
|
+
|
|
254
|
+
/** Runtime context negotiated once per active Protocol V2 link. */
|
|
255
|
+
private protocolV2RuntimeContext?: ProtocolInfo;
|
|
256
|
+
|
|
257
|
+
/** Coalesces concurrent first-use runtime negotiation on the same active link. */
|
|
258
|
+
private protocolV2RuntimeContextPromise?: Promise<ProtocolInfo>;
|
|
259
|
+
|
|
260
|
+
/** Invalidates an in-flight runtime-context response without adding a transport epoch. */
|
|
261
|
+
private protocolV2RuntimeContextRequestToken?: object;
|
|
262
|
+
|
|
263
|
+
private protocolV2UiInteraction?: {
|
|
264
|
+
interactionId: string;
|
|
265
|
+
phaseCounter: number;
|
|
266
|
+
sequence: number;
|
|
267
|
+
opened: boolean;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
private protocolV2UiInteractionCounter = 0;
|
|
271
|
+
|
|
272
|
+
get state() {
|
|
273
|
+
return this.stateStore.getState();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get features(): Features | undefined {
|
|
277
|
+
if (!this.state) return undefined;
|
|
278
|
+
return projectFeatures(this.state);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
set features(features: Features | undefined) {
|
|
282
|
+
this.stateStore = new DeviceStateStore();
|
|
283
|
+
if (features) {
|
|
284
|
+
this.stateStore.update(mapFeaturesToState(features), 'compatibility');
|
|
285
|
+
const { passphraseState } = features;
|
|
286
|
+
const sessionId = features.sessionId ?? features.session_id;
|
|
287
|
+
const deviceKey = this.getSessionCacheDeviceKey(features.deviceId ?? undefined);
|
|
288
|
+
if (passphraseState && sessionId && deviceKey) {
|
|
289
|
+
this.passphraseState = passphraseState;
|
|
290
|
+
deviceWalletSessionStore.set(deviceKey, passphraseState, sessionId);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
204
294
|
|
|
205
295
|
runPromise?: Deferred<void> | null;
|
|
206
296
|
|
|
297
|
+
/** Resolves only after the active run has completed its release path. */
|
|
298
|
+
private runCleanupPromise?: Promise<void>;
|
|
299
|
+
|
|
207
300
|
externalState: string[] = [];
|
|
208
301
|
|
|
209
302
|
unavailableCapabilities: UnavailableCapabilities = {};
|
|
@@ -254,38 +347,46 @@ export class Device extends EventEmitter {
|
|
|
254
347
|
|
|
255
348
|
// simplified object to pass via postMessage
|
|
256
349
|
toMessageObject(): DeviceTyped | null {
|
|
257
|
-
if (this.isUnacquired()) return null;
|
|
350
|
+
if (this.isUnacquired() || !this.features) return null;
|
|
258
351
|
|
|
259
352
|
const env = DataManager.getSettings('env');
|
|
260
353
|
const deviceType = this.getCurrentDeviceType();
|
|
261
354
|
|
|
262
355
|
const bleName = this.getCurrentBleName();
|
|
263
|
-
const
|
|
356
|
+
const displayName = this.getCurrentDisplayName();
|
|
264
357
|
const serialNo = this.getCurrentSerialNo();
|
|
265
358
|
const connectId = this.getConnectId();
|
|
266
359
|
const deviceId = this.getCurrentDeviceId() || null;
|
|
267
360
|
|
|
268
361
|
const { features } = this;
|
|
362
|
+
const state = this.state ? createPublicDeviceState(this.state) : undefined;
|
|
269
363
|
|
|
270
364
|
return {
|
|
271
|
-
/** Android uses
|
|
365
|
+
/** Android uses a MAC address, while iOS and USB use transport-specific identifiers. */
|
|
272
366
|
connectId: DataManager.isBleConnect(env) ? this.mainId || null : connectId,
|
|
273
|
-
/**
|
|
367
|
+
/** Persist this after the first active probe so later calls do not need to guess. */
|
|
368
|
+
connectProtocol: this.originalDescriptor.protocolType,
|
|
369
|
+
/** Stable physical-device identity. */
|
|
370
|
+
serialNo,
|
|
371
|
+
/** @deprecated Use serialNo instead. */
|
|
274
372
|
uuid: serialNo,
|
|
275
373
|
commType: this.originalDescriptor.commType,
|
|
276
374
|
sdkInstanceId: this.sdkInstanceId,
|
|
277
375
|
instanceId: this.instanceId,
|
|
278
376
|
createdAt: this.createdAt,
|
|
279
377
|
deviceType,
|
|
280
|
-
/** ID
|
|
378
|
+
/** Wallet-lifecycle ID; changes after the device is wiped or reinitialized. */
|
|
281
379
|
deviceId,
|
|
282
380
|
path: this.originalDescriptor?.path,
|
|
283
381
|
bleName,
|
|
284
|
-
name: bleName ||
|
|
285
|
-
|
|
382
|
+
name: bleName || displayName || `OneKey ${deviceType?.toUpperCase()}`,
|
|
383
|
+
// Keep the legacy top-level field string-compatible while preserving
|
|
384
|
+
// the canonical nullable value at state.identity.label.
|
|
385
|
+
label: displayName ?? '',
|
|
386
|
+
status: this.getStatus(),
|
|
286
387
|
mode: this.getMode(),
|
|
287
388
|
features,
|
|
288
|
-
|
|
389
|
+
state,
|
|
289
390
|
firmwareVersion: this.getFirmwareVersion(),
|
|
290
391
|
bleFirmwareVersion: this.getBLEFirmwareVersion(),
|
|
291
392
|
unavailableCapabilities: this.unavailableCapabilities,
|
|
@@ -296,13 +397,20 @@ export class Device extends EventEmitter {
|
|
|
296
397
|
* Device connect
|
|
297
398
|
* @returns {Promise<boolean>}
|
|
298
399
|
*/
|
|
299
|
-
connect(
|
|
400
|
+
connect(
|
|
401
|
+
connectProtocol?: HardwareConnectProtocol,
|
|
402
|
+
options?: { forceProtocolDetection?: boolean }
|
|
403
|
+
) {
|
|
300
404
|
const env = DataManager.getSettings('env');
|
|
301
405
|
// eslint-disable-next-line no-async-promise-executor
|
|
302
406
|
return new Promise<boolean>(async (resolve, reject) => {
|
|
303
407
|
if (DataManager.isBleConnect(env)) {
|
|
408
|
+
if (this.hasDeviceAcquire() && this.commands && !this.commands.disposed) {
|
|
409
|
+
resolve(true);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
304
412
|
try {
|
|
305
|
-
await this.acquire(connectProtocol);
|
|
413
|
+
await this.acquire(connectProtocol, options);
|
|
306
414
|
resolve(true);
|
|
307
415
|
} catch (error) {
|
|
308
416
|
reject(error);
|
|
@@ -312,7 +420,7 @@ export class Device extends EventEmitter {
|
|
|
312
420
|
// 不存在 Session ID 或存在 Session ID 但设备在别处使用,都需要 acquire 获取最新 sessionID
|
|
313
421
|
if (!this.mainId || (!this.isUsedHere() && this.originalDescriptor)) {
|
|
314
422
|
try {
|
|
315
|
-
await this.acquire(connectProtocol);
|
|
423
|
+
await this.acquire(connectProtocol, options);
|
|
316
424
|
resolve(true);
|
|
317
425
|
} catch (error) {
|
|
318
426
|
reject(error);
|
|
@@ -328,25 +436,33 @@ export class Device extends EventEmitter {
|
|
|
328
436
|
}
|
|
329
437
|
|
|
330
438
|
async acquire(
|
|
331
|
-
|
|
332
|
-
options?: { throwOnRunPromiseError?: boolean }
|
|
439
|
+
expectedProtocol?: HardwareConnectProtocol,
|
|
440
|
+
options?: { throwOnRunPromiseError?: boolean; forceProtocolDetection?: boolean }
|
|
333
441
|
) {
|
|
442
|
+
const attempt = this.connectionAttempt;
|
|
443
|
+
this.throwIfInterruptedByUser();
|
|
334
444
|
const env = DataManager.getSettings('env');
|
|
335
445
|
const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
|
|
336
|
-
const
|
|
446
|
+
const previousProtocol = this.originalDescriptor.protocolType;
|
|
447
|
+
// A protocol stored after a successful probe is authoritative. Only the explicit
|
|
448
|
+
// first-connection/recovery path may bypass it and probe both protocols again.
|
|
449
|
+
const strictProtocol = options?.forceProtocolDetection
|
|
450
|
+
? undefined
|
|
451
|
+
: expectedProtocol ?? this.originalDescriptor.protocolType;
|
|
337
452
|
try {
|
|
338
453
|
let acquireResult: unknown;
|
|
339
454
|
if (DataManager.isBleConnect(env)) {
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
//
|
|
343
|
-
//
|
|
344
|
-
// 因此对 BLE acquire 恒清理是有意为之。
|
|
455
|
+
// acquire starts a new BLE session. Any previous runPromise belongs to a dead
|
|
456
|
+
// session, such as an interrupted probe or firmware-update reboot, and would
|
|
457
|
+
// otherwise block the new session. Device cannot distinguish recovery from a
|
|
458
|
+
// regular acquire, so BLE always clears it intentionally.
|
|
345
459
|
acquireResult = await this.deviceConnector?.acquire(
|
|
346
460
|
this.originalDescriptor.id,
|
|
347
461
|
undefined,
|
|
348
462
|
true,
|
|
349
|
-
|
|
463
|
+
strictProtocol,
|
|
464
|
+
undefined,
|
|
465
|
+
options?.forceProtocolDetection
|
|
350
466
|
);
|
|
351
467
|
this.mainId = (acquireResult as any)?.uuid ?? '';
|
|
352
468
|
Log.debug('Expected uuid:', this.mainId);
|
|
@@ -355,30 +471,68 @@ export class Device extends EventEmitter {
|
|
|
355
471
|
this.originalDescriptor.path,
|
|
356
472
|
this.originalDescriptor.session,
|
|
357
473
|
undefined,
|
|
358
|
-
|
|
474
|
+
strictProtocol,
|
|
475
|
+
undefined,
|
|
476
|
+
options?.forceProtocolDetection
|
|
359
477
|
);
|
|
360
478
|
this.mainId = acquireResult as string | undefined;
|
|
361
479
|
Log.debug('Expected session id:', this.mainId);
|
|
362
480
|
}
|
|
363
|
-
this.deviceAcquired = true;
|
|
364
|
-
this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
|
|
365
|
-
|
|
366
481
|
// Propagate protocol version detected during acquire.
|
|
367
482
|
const detectedProtocol =
|
|
368
483
|
(acquireResult as { protocolType?: HardwareConnectProtocol } | undefined)?.protocolType ??
|
|
369
484
|
TransportManager.transport?.getProtocolType?.(
|
|
370
485
|
DataManager.isBleConnect(env) ? this.originalDescriptor.id : this.originalDescriptor.path
|
|
371
486
|
);
|
|
487
|
+
if (options?.forceProtocolDetection && !detectedProtocol) {
|
|
488
|
+
throw ERRORS.TypedError(
|
|
489
|
+
HardwareErrorCode.RuntimeError,
|
|
490
|
+
`Active protocol detection returned no protocol for ${
|
|
491
|
+
this.originalDescriptor.path || this.originalDescriptor.id
|
|
492
|
+
}`
|
|
493
|
+
);
|
|
494
|
+
}
|
|
372
495
|
if (detectedProtocol) {
|
|
373
496
|
this.originalDescriptor.protocolType = detectedProtocol;
|
|
374
497
|
}
|
|
498
|
+
if (this.interruptedAttempt === attempt || this.connectionAttempt !== attempt) {
|
|
499
|
+
const session = this.mainId;
|
|
500
|
+
if (session && this.deviceConnector?.disconnect) {
|
|
501
|
+
await this.deviceConnector.disconnect(session).catch(disconnectError => {
|
|
502
|
+
Log.debug('Ignored disconnect after user cancel during acquire', disconnectError);
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
|
|
506
|
+
}
|
|
507
|
+
this.deviceAcquired = true;
|
|
508
|
+
this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
|
|
375
509
|
|
|
376
510
|
if (this.commands) {
|
|
377
511
|
await this.commands.dispose(false);
|
|
378
512
|
}
|
|
379
513
|
|
|
380
514
|
this.commands = new DeviceCommands(this, this.mainId ?? '');
|
|
515
|
+
// Protocol V2 runtime metadata belongs to one active transport link. A
|
|
516
|
+
// successful acquire creates a fresh link/session, so never carry cached
|
|
517
|
+
// ProtocolInfo or pre-initialize state across that boundary.
|
|
518
|
+
this.invalidateProtocolV2RuntimeState();
|
|
381
519
|
} catch (error) {
|
|
520
|
+
if (options?.forceProtocolDetection) {
|
|
521
|
+
this.originalDescriptor.protocolType = previousProtocol;
|
|
522
|
+
const failedSession = this.mainId;
|
|
523
|
+
this.deviceAcquired = false;
|
|
524
|
+
if (failedSession) {
|
|
525
|
+
try {
|
|
526
|
+
await this.deviceConnector?.release?.(failedSession, false);
|
|
527
|
+
} catch (releaseError) {
|
|
528
|
+
Log.debug('Failed to release an unsuccessful protocol probe', releaseError);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (!DataManager.isBleConnect(env)) {
|
|
532
|
+
this.mainId = null;
|
|
533
|
+
this.updateDescriptor({ session: null } as DeviceDescriptor);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
382
536
|
if (options?.throwOnRunPromiseError) {
|
|
383
537
|
throw error;
|
|
384
538
|
}
|
|
@@ -420,7 +574,8 @@ export class Device extends EventEmitter {
|
|
|
420
574
|
}
|
|
421
575
|
}
|
|
422
576
|
try {
|
|
423
|
-
|
|
577
|
+
// BLE releases even when keepSession is set, so forward the intent.
|
|
578
|
+
await this.deviceConnector?.release(this.mainId, false, this.keepSession);
|
|
424
579
|
this.updateDescriptor({ session: null } as DeviceDescriptor);
|
|
425
580
|
} catch (err) {
|
|
426
581
|
Log.error('[Device] release error: ', err);
|
|
@@ -482,12 +637,11 @@ export class Device extends EventEmitter {
|
|
|
482
637
|
}
|
|
483
638
|
|
|
484
639
|
/**
|
|
485
|
-
*
|
|
640
|
+
* Canonical protocol discriminator.
|
|
486
641
|
*
|
|
487
|
-
* descriptor.protocolType
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
* 或从 features 反推。
|
|
642
|
+
* descriptor.protocolType is established by active probing; V2 features are mapped
|
|
643
|
+
* from DeviceInfoGet. All protocol branches must use this method instead of reading
|
|
644
|
+
* originalDescriptor.protocolType directly or inferring a protocol from features.
|
|
491
645
|
*/
|
|
492
646
|
getProtocol(): 'V1' | 'V2' {
|
|
493
647
|
return this.originalDescriptor.protocolType === 'V2' ? 'V2' : 'V1';
|
|
@@ -498,53 +652,76 @@ export class Device extends EventEmitter {
|
|
|
498
652
|
}
|
|
499
653
|
|
|
500
654
|
getCurrentDeviceType() {
|
|
501
|
-
return
|
|
655
|
+
return this.state?.identity.deviceType ?? EDeviceType.Unknown;
|
|
502
656
|
}
|
|
503
657
|
|
|
504
658
|
getCurrentDeviceId() {
|
|
505
|
-
return this.
|
|
659
|
+
return this.state?.identity.deviceId || undefined;
|
|
506
660
|
}
|
|
507
661
|
|
|
508
662
|
getCurrentSerialNo() {
|
|
509
|
-
return this.
|
|
663
|
+
return this.state?.identity.serialNo ?? '';
|
|
510
664
|
}
|
|
511
665
|
|
|
512
666
|
getConnectId() {
|
|
513
667
|
const serialNo = this.getCurrentSerialNo();
|
|
514
668
|
if (serialNo) return serialNo;
|
|
515
669
|
|
|
516
|
-
// connectId
|
|
517
|
-
//
|
|
670
|
+
// connectId is an internal routing key. Falling back to the transport descriptor
|
|
671
|
+
// does not change the business meaning of features.serialNo or deviceId.
|
|
518
672
|
return this.originalDescriptor.path || this.originalDescriptor.id || '';
|
|
519
673
|
}
|
|
520
674
|
|
|
521
675
|
getCurrentBleName() {
|
|
522
|
-
|
|
676
|
+
const bleName = this.state?.identity.bleName ?? null;
|
|
677
|
+
return bleName ? canonicalizePro2BleAdvertisementName(bleName) : null;
|
|
523
678
|
}
|
|
524
679
|
|
|
525
680
|
getCurrentLabel() {
|
|
526
|
-
return
|
|
681
|
+
return this.state?.identity.label ?? null;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
getCurrentDisplayName() {
|
|
685
|
+
if (!this.state) return null;
|
|
686
|
+
|
|
687
|
+
const label = this.getCurrentLabel();
|
|
688
|
+
if (label) return label;
|
|
689
|
+
|
|
690
|
+
const bleName = this.getCurrentBleName();
|
|
691
|
+
if (bleName) return bleName;
|
|
692
|
+
|
|
693
|
+
const deviceType = this.getCurrentDeviceType();
|
|
694
|
+
if (deviceType === EDeviceType.ClassicPure) {
|
|
695
|
+
return 'OneKey Classic 1S';
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return `OneKey ${deviceType.charAt(0).toUpperCase() + deviceType.slice(1)}`;
|
|
527
699
|
}
|
|
528
700
|
|
|
529
701
|
getCurrentPassphraseProtection() {
|
|
530
|
-
return this.
|
|
702
|
+
return this.state?.status.passphraseProtection;
|
|
531
703
|
}
|
|
532
704
|
|
|
533
705
|
getCurrentFirmwareType() {
|
|
534
|
-
return
|
|
706
|
+
return this.state?.identity.firmwareType ?? EFirmwareType.Universal;
|
|
535
707
|
}
|
|
536
708
|
|
|
537
709
|
getCurrentFirmwareVersionString() {
|
|
538
|
-
return
|
|
710
|
+
return parseDeviceVersion(this.state?.versions.firmware).join('.');
|
|
539
711
|
}
|
|
540
712
|
|
|
541
713
|
getCurrentBLEFirmwareVersionString() {
|
|
542
|
-
if (!this.
|
|
543
|
-
return
|
|
714
|
+
if (!this.state) return undefined;
|
|
715
|
+
return parseDeviceVersion(this.state.versions.ble).join('.');
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
getCurrentBootloaderVersionString() {
|
|
719
|
+
if (!this.state) return undefined;
|
|
720
|
+
return parseDeviceVersion(this.state.versions.bootloader).join('.');
|
|
544
721
|
}
|
|
545
722
|
|
|
546
723
|
getCurrentSafetyChecks() {
|
|
547
|
-
return this.
|
|
724
|
+
return this.state?.settings.safetyChecks;
|
|
548
725
|
}
|
|
549
726
|
|
|
550
727
|
getCurrentMethodVersionRange(
|
|
@@ -557,6 +734,7 @@ export class Device extends EventEmitter {
|
|
|
557
734
|
// Most-specific model first; must match getMethodVersionRange in deviceInfoUtils,
|
|
558
735
|
// otherwise e.g. Classic1s resolves the looser model_mini range before model_classic1s.
|
|
559
736
|
const modelFallbacks: IDeviceModel[] = [
|
|
737
|
+
'model_pro2',
|
|
560
738
|
'model_classic1s',
|
|
561
739
|
'model_classic',
|
|
562
740
|
'model_mini',
|
|
@@ -576,7 +754,8 @@ export class Device extends EventEmitter {
|
|
|
576
754
|
if (
|
|
577
755
|
deviceType === EDeviceType.Touch ||
|
|
578
756
|
deviceType === EDeviceType.Pro ||
|
|
579
|
-
deviceType === EDeviceType.Pro2
|
|
757
|
+
deviceType === EDeviceType.Pro2 ||
|
|
758
|
+
deviceType === EDeviceType.Neo
|
|
580
759
|
) {
|
|
581
760
|
return { support: true };
|
|
582
761
|
}
|
|
@@ -589,13 +768,12 @@ export class Device extends EventEmitter {
|
|
|
589
768
|
}
|
|
590
769
|
|
|
591
770
|
supportInputPinOnSoftware(): SupportFeatureType {
|
|
592
|
-
if (this.features) return supportInputPinOnSoftware(this.features);
|
|
593
|
-
|
|
594
771
|
const deviceType = this.getCurrentDeviceType();
|
|
595
772
|
if (
|
|
596
773
|
deviceType === EDeviceType.Touch ||
|
|
597
774
|
deviceType === EDeviceType.Pro ||
|
|
598
|
-
deviceType === EDeviceType.Pro2
|
|
775
|
+
deviceType === EDeviceType.Pro2 ||
|
|
776
|
+
deviceType === EDeviceType.Neo
|
|
599
777
|
) {
|
|
600
778
|
return { support: false };
|
|
601
779
|
}
|
|
@@ -608,15 +786,12 @@ export class Device extends EventEmitter {
|
|
|
608
786
|
}
|
|
609
787
|
|
|
610
788
|
supportModifyHomescreen(): SupportFeatureType {
|
|
611
|
-
// Pro2
|
|
612
|
-
//
|
|
613
|
-
// 包含 homescreen 字段,V2 固件从首个版本即支持修改主屏。
|
|
789
|
+
// Pro2 has an independent 1.x version line and must not use the Touch/Pro 3.4.0
|
|
790
|
+
// threshold. ApplySettings includes homescreen from the first V2 firmware version.
|
|
614
791
|
if (this.isProtocolV2()) {
|
|
615
792
|
return { support: true };
|
|
616
793
|
}
|
|
617
794
|
|
|
618
|
-
if (this.features) return supportModifyHomescreen(this.features);
|
|
619
|
-
|
|
620
795
|
const deviceType = this.getCurrentDeviceType();
|
|
621
796
|
if (DeviceModelToTypes.model_mini.includes(deviceType)) {
|
|
622
797
|
return { support: true };
|
|
@@ -632,17 +807,25 @@ export class Device extends EventEmitter {
|
|
|
632
807
|
const deviceId = _deviceId || this.getCurrentDeviceId();
|
|
633
808
|
if (deviceId) return deviceId;
|
|
634
809
|
if (this.isProtocolV2()) {
|
|
635
|
-
return this.originalDescriptor.path
|
|
810
|
+
return this.originalDescriptor.path;
|
|
636
811
|
}
|
|
637
812
|
return undefined;
|
|
638
813
|
}
|
|
639
814
|
|
|
815
|
+
private reconcileSessionCacheDeviceIdentity(previousDeviceId?: string) {
|
|
816
|
+
deviceWalletSessionStore.reconcileDeviceIdentity({
|
|
817
|
+
temporaryKey: this.isProtocolV2() ? this.originalDescriptor.path : undefined,
|
|
818
|
+
previousDeviceId,
|
|
819
|
+
nextDeviceId: this.getCurrentDeviceId(),
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
|
|
640
823
|
getInternalState(_deviceId?: string) {
|
|
641
824
|
Log.debug(
|
|
642
825
|
'getInternalState session param: ',
|
|
643
826
|
`device_id: ${_deviceId}`,
|
|
644
|
-
`
|
|
645
|
-
`
|
|
827
|
+
`currentDeviceId: ${this.getCurrentDeviceId()}`,
|
|
828
|
+
`hasPassphraseState: ${Boolean(this.passphraseState)}`
|
|
646
829
|
);
|
|
647
830
|
|
|
648
831
|
const deviceId = this.getSessionCacheDeviceKey(_deviceId);
|
|
@@ -658,19 +841,26 @@ export class Device extends EventEmitter {
|
|
|
658
841
|
return deviceWalletSessionStore.get(deviceId, this.passphraseState);
|
|
659
842
|
}
|
|
660
843
|
|
|
844
|
+
getStandardInternalState(_deviceId?: string) {
|
|
845
|
+
const deviceId = this.getSessionCacheDeviceKey(_deviceId);
|
|
846
|
+
if (!deviceId) return undefined;
|
|
847
|
+
return deviceWalletSessionStore.getStandard(deviceId);
|
|
848
|
+
}
|
|
849
|
+
|
|
661
850
|
// attach to pin to fix internal state
|
|
662
851
|
updateInternalState(
|
|
663
852
|
enablePassphrase: boolean,
|
|
664
853
|
passphraseState: string | undefined,
|
|
665
854
|
deviceId: string | undefined,
|
|
666
855
|
sessionId: string | null = null,
|
|
667
|
-
featuresSessionId: string | null = null
|
|
856
|
+
featuresSessionId: string | null = null,
|
|
857
|
+
walletType: 'standard' | 'hidden' = 'hidden'
|
|
668
858
|
) {
|
|
669
859
|
Log.debug(
|
|
670
860
|
'updateInternalState session param: ',
|
|
671
861
|
`device_id: ${deviceId}`,
|
|
672
862
|
`enablePassphrase: ${enablePassphrase}`,
|
|
673
|
-
`
|
|
863
|
+
`hasPassphraseState: ${Boolean(passphraseState)}`,
|
|
674
864
|
`hasSessionId: ${Boolean(sessionId)}`,
|
|
675
865
|
`hasFeaturesSessionId: ${Boolean(featuresSessionId)}`
|
|
676
866
|
);
|
|
@@ -681,7 +871,15 @@ export class Device extends EventEmitter {
|
|
|
681
871
|
if (enablePassphrase) {
|
|
682
872
|
const walletSessionId =
|
|
683
873
|
sessionId || featuresSessionId || deviceWalletSessionStore.getPending(cacheDeviceKey);
|
|
684
|
-
|
|
874
|
+
if (walletType === 'standard') {
|
|
875
|
+
deviceWalletSessionStore.setStandard(
|
|
876
|
+
cacheDeviceKey,
|
|
877
|
+
passphraseState,
|
|
878
|
+
walletSessionId ?? undefined
|
|
879
|
+
);
|
|
880
|
+
} else {
|
|
881
|
+
deviceWalletSessionStore.set(cacheDeviceKey, passphraseState, walletSessionId ?? undefined);
|
|
882
|
+
}
|
|
685
883
|
}
|
|
686
884
|
|
|
687
885
|
deviceWalletSessionStore.deletePending(cacheDeviceKey);
|
|
@@ -692,8 +890,8 @@ export class Device extends EventEmitter {
|
|
|
692
890
|
'setInternalState session param: ',
|
|
693
891
|
`hasState: ${Boolean(state)}`,
|
|
694
892
|
`initSession: ${initSession}`,
|
|
695
|
-
`deviceId: ${this.
|
|
696
|
-
`
|
|
893
|
+
`deviceId: ${this.getCurrentDeviceId()}`,
|
|
894
|
+
`hasPassphraseState: ${Boolean(this.passphraseState)}`
|
|
697
895
|
);
|
|
698
896
|
|
|
699
897
|
if (!this.passphraseState && !initSession) return;
|
|
@@ -720,61 +918,118 @@ export class Device extends EventEmitter {
|
|
|
720
918
|
}
|
|
721
919
|
}
|
|
722
920
|
|
|
921
|
+
clearStandardInternalState(_deviceId?: string) {
|
|
922
|
+
const deviceId = this.getSessionCacheDeviceKey(_deviceId);
|
|
923
|
+
if (!deviceId) return;
|
|
924
|
+
deviceWalletSessionStore.deleteStandard(deviceId);
|
|
925
|
+
}
|
|
926
|
+
|
|
723
927
|
async initialize(options?: InitOptions) {
|
|
724
|
-
|
|
928
|
+
this.throwIfInterruptedByUser();
|
|
929
|
+
// Protocol V2 does not support legacy Initialize; use its dedicated flow.
|
|
725
930
|
if (this.isProtocolV2()) {
|
|
726
931
|
this.passphraseState = options?.passphraseState;
|
|
727
|
-
if (this.
|
|
728
|
-
if (this.
|
|
932
|
+
if (this.state && !options?.initSession && !this.protocolV2StateNeedsReload) {
|
|
933
|
+
if (this.state.status.mode === 'bootloader' || this.state.status.mode === 'romloader') {
|
|
729
934
|
return;
|
|
730
935
|
}
|
|
731
|
-
//
|
|
732
|
-
//
|
|
733
|
-
// 用字段级合并保留已有版本和 SE 信息。
|
|
734
|
-
await this._refreshProtocolV2Status(options);
|
|
936
|
+
// Normal calls reuse the cache. Explicit getDeviceState refreshes, unlock flow,
|
|
937
|
+
// and device events update dynamic state without polling on every SDK call.
|
|
735
938
|
return;
|
|
736
939
|
}
|
|
737
940
|
await this._initializeProtocolV2(options);
|
|
941
|
+
this.protocolV2StateNeedsReload = false;
|
|
738
942
|
return;
|
|
739
943
|
}
|
|
740
944
|
|
|
741
|
-
|
|
945
|
+
try {
|
|
946
|
+
const callInitialize = async (payload: Record<string, unknown>, initSession?: boolean) => {
|
|
947
|
+
const initStartAt = Date.now();
|
|
948
|
+
const { message } = await this.commands.typedCall('Initialize', 'Features', payload, {
|
|
949
|
+
// iOS BLE bound devices can need close to 20 seconds.
|
|
950
|
+
timeoutMs: options?.timeoutMs ?? 25 * 1000,
|
|
951
|
+
});
|
|
952
|
+
this.setLastInitializeDuration(Date.now() - initStartAt);
|
|
953
|
+
this._updateFeatures(message, initSession);
|
|
954
|
+
await TransportManager.reconfigure(this.features);
|
|
955
|
+
};
|
|
742
956
|
|
|
743
|
-
|
|
957
|
+
const expectedDeviceId = options?.deviceId;
|
|
958
|
+
|
|
959
|
+
if (expectedDeviceId && !(this.features && this.checkDeviceId(expectedDeviceId))) {
|
|
960
|
+
// No locally-cached evidence that the device at this path is the
|
|
961
|
+
// expected one (first contact, or the cached features already disagree
|
|
962
|
+
// with the caller). Establish identity with a context-free Initialize
|
|
963
|
+
// BEFORE any wallet context (session_id / passphrase_state) goes on
|
|
964
|
+
// the wire. In normal flows features are always fresh — enumerate /
|
|
965
|
+
// getFeatures run first and every call response refreshes them — so
|
|
966
|
+
// this extra round trip is confined to the ambiguous cases where the
|
|
967
|
+
// disclosure risk actually lives.
|
|
968
|
+
this.passphraseState = undefined;
|
|
969
|
+
await callInitialize({ is_contains_attach: true });
|
|
970
|
+
if (!this.checkDeviceId(expectedDeviceId)) {
|
|
971
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
744
974
|
|
|
745
|
-
|
|
746
|
-
this.clearInternalState(options?.deviceId);
|
|
747
|
-
}
|
|
975
|
+
this.passphraseState = options?.passphraseState;
|
|
748
976
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
payload.session_id = internalState;
|
|
753
|
-
}
|
|
977
|
+
if (options?.initSession) {
|
|
978
|
+
this.clearInternalState(options?.deviceId);
|
|
979
|
+
}
|
|
754
980
|
|
|
755
|
-
|
|
756
|
-
payload
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
981
|
+
const internalState = this.getInternalState(options?.deviceId);
|
|
982
|
+
const payload: Record<string, unknown> = {
|
|
983
|
+
passphrase_state: options?.passphraseState,
|
|
984
|
+
is_contains_attach: true,
|
|
985
|
+
};
|
|
986
|
+
if (internalState) {
|
|
987
|
+
payload.session_id = internalState;
|
|
988
|
+
}
|
|
989
|
+
if (options?.deriveCardano) {
|
|
990
|
+
payload.derive_cardano = true;
|
|
991
|
+
}
|
|
760
992
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
993
|
+
if (this.features) {
|
|
994
|
+
// Re-sync the V1 message schema for THIS device before encoding
|
|
995
|
+
// Initialize: the process-global schema may still reflect another
|
|
996
|
+
// device (e.g. legacy-firmware Touch/Mini) on multi-device setups, and
|
|
997
|
+
// a stale legacy schema would silently strip passphrase_state /
|
|
998
|
+
// is_contains_attach from the wire message. Local operation, no wire
|
|
999
|
+
// I/O; a no-op when the schema is unchanged.
|
|
1000
|
+
await TransportManager.reconfigure(this.features);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
// Initialize's own Features response carries device_id, so the physical
|
|
1004
|
+
// device identity is validated on the same round trip instead of via a
|
|
1005
|
+
// separate read-only GetFeatures preflight (which doubled the wire cost
|
|
1006
|
+
// of every deviceId-carrying call). The method fn has not run yet, so a
|
|
1007
|
+
// mismatch still fails before any wallet data can be derived, with the
|
|
1008
|
+
// same DeviceCheckDeviceIdError. Wallet-context selection is unchanged:
|
|
1009
|
+
// it is decided by the Initialize payload above either way.
|
|
1010
|
+
const assertExpectedDeviceIdentity = () => {
|
|
1011
|
+
if (expectedDeviceId && !this.checkDeviceId(expectedDeviceId)) {
|
|
1012
|
+
// The mismatched Initialize may have cached a session under the wrong
|
|
1013
|
+
// device's identity; drop it so no wallet context survives from it.
|
|
1014
|
+
// (This also evicts any session the wrong device legitimately cached
|
|
1015
|
+
// under the same passphraseState — a deliberate conservative purge
|
|
1016
|
+
// after a physical-swap event, consistent with
|
|
1017
|
+
// reconcileDeviceIdentity purging the previous device's sessions.)
|
|
1018
|
+
this.clearInternalState();
|
|
1019
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceCheckDeviceIdError);
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
|
|
1023
|
+
try {
|
|
1024
|
+
await callInitialize(payload, options?.initSession);
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
// callInitialize can fail AFTER the wire call cached the session (e.g.
|
|
1027
|
+
// TransportManager.reconfigure rejecting); the identity check must
|
|
1028
|
+
// still run so a wrong-device session never survives the error path.
|
|
1029
|
+
assertExpectedDeviceIdentity();
|
|
1030
|
+
throw error;
|
|
1031
|
+
}
|
|
1032
|
+
assertExpectedDeviceIdentity();
|
|
778
1033
|
} catch (error) {
|
|
779
1034
|
Log.error('Initialization failed:', error);
|
|
780
1035
|
throw error;
|
|
@@ -784,59 +1039,34 @@ export class Device extends EventEmitter {
|
|
|
784
1039
|
/**
|
|
785
1040
|
* Device initialization over Protocol V2.
|
|
786
1041
|
*
|
|
787
|
-
* Protocol V2
|
|
788
|
-
*
|
|
1042
|
+
* Protocol V2 bypasses legacy Initialize/GetFeatures and builds its canonical
|
|
1043
|
+
* features state directly from DeviceInfoGet.
|
|
789
1044
|
*/
|
|
790
1045
|
private async _initializeProtocolV2(options?: InitOptions) {
|
|
791
1046
|
Log.debug('Initialize device via Protocol V2 features adapter');
|
|
792
1047
|
|
|
793
1048
|
try {
|
|
794
|
-
//
|
|
795
|
-
//
|
|
796
|
-
// 且 reject 后底层调用仍会残留。
|
|
1049
|
+
// typedCall applies the request timeout. An outer Promise.race would leak its
|
|
1050
|
+
// timer and leave the underlying call active after rejection.
|
|
797
1051
|
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
798
1052
|
commands: this.commands,
|
|
799
1053
|
timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
|
|
800
1054
|
});
|
|
801
|
-
//
|
|
802
|
-
//
|
|
803
|
-
|
|
804
|
-
Log.debug('Protocol V2 features:', features);
|
|
805
|
-
this.featuresNeedsReload = false;
|
|
1055
|
+
// The default request excludes SE/hash data and therefore uses basic scope.
|
|
1056
|
+
// Full version and verification data require getDeviceState({ scope: 'firmware' }).
|
|
1057
|
+
await this.probeProtocolV2RuntimeState(deviceInfo, options?.protocolV2DeviceInfoTimeoutMs);
|
|
806
1058
|
} catch (error) {
|
|
807
1059
|
Log.error('Protocol V2 initialization failed:', error);
|
|
808
1060
|
throw error;
|
|
809
1061
|
}
|
|
810
1062
|
}
|
|
811
1063
|
|
|
812
|
-
/**
|
|
813
|
-
* Protocol V2 的轻量状态刷新(每次 run 前调用)。
|
|
814
|
-
*
|
|
815
|
-
* 请求 hw + coprocessor + status(不含 fw/SE target):status 提供 init_states / label /
|
|
816
|
-
* passphrase_enabled 等会在设备端变化的字段;hw/coprocessor 提供 serialNo / bleName。
|
|
817
|
-
* versions 为空时按字段级合并保留旧值,verify 数据不会被降级。
|
|
818
|
-
*/
|
|
819
|
-
private async _refreshProtocolV2Status(options?: InitOptions) {
|
|
820
|
-
try {
|
|
821
|
-
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
822
|
-
commands: this.commands,
|
|
823
|
-
request: PROTOCOL_V2_STATUS_DEVICE_INFO_REQUEST,
|
|
824
|
-
timeoutMs: options?.protocolV2DeviceInfoTimeoutMs,
|
|
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
1064
|
async getFeatures() {
|
|
835
1065
|
if (this.isProtocolV2()) {
|
|
836
1066
|
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
837
1067
|
commands: this.commands,
|
|
838
1068
|
});
|
|
839
|
-
return this.
|
|
1069
|
+
return this.probeProtocolV2RuntimeState(deviceInfo);
|
|
840
1070
|
}
|
|
841
1071
|
|
|
842
1072
|
const { message } = await this.commands.typedCall('GetFeatures', 'Features', {});
|
|
@@ -844,61 +1074,355 @@ export class Device extends EventEmitter {
|
|
|
844
1074
|
return this.features;
|
|
845
1075
|
}
|
|
846
1076
|
|
|
1077
|
+
async getDeviceState(params: DeviceStateReadOptions = {}) {
|
|
1078
|
+
const refresh = new Set(params.refreshSections ?? []);
|
|
1079
|
+
const getProtocolV2DeviceInfoRequest = () => {
|
|
1080
|
+
if (refresh.has('verification')) return PROTOCOL_V2_FULL_DEVICE_INFO_REQUEST;
|
|
1081
|
+
if (refresh.has('versions')) return PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST;
|
|
1082
|
+
return PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST;
|
|
1083
|
+
};
|
|
1084
|
+
let initializedWithDeviceInfo = false;
|
|
1085
|
+
let refreshedDeviceInfo: ProtocolV2DeviceInfo | undefined;
|
|
1086
|
+
|
|
1087
|
+
if (!this.state) {
|
|
1088
|
+
if (this.isProtocolV2()) {
|
|
1089
|
+
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
1090
|
+
commands: this.commands,
|
|
1091
|
+
request: getProtocolV2DeviceInfoRequest(),
|
|
1092
|
+
});
|
|
1093
|
+
await this.probeProtocolV2RuntimeState(deviceInfo);
|
|
1094
|
+
refreshedDeviceInfo = deviceInfo;
|
|
1095
|
+
initializedWithDeviceInfo = true;
|
|
1096
|
+
} else {
|
|
1097
|
+
await this.getFeatures();
|
|
1098
|
+
}
|
|
1099
|
+
} else if (!this.isProtocolV2() && refresh.size > 0) {
|
|
1100
|
+
await this.getFeatures();
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
const supportsProtocolV1OnekeyFeatures =
|
|
1104
|
+
this.getCurrentDeviceType() === EDeviceType.Touch ||
|
|
1105
|
+
this.getCurrentDeviceType() === EDeviceType.Pro;
|
|
1106
|
+
if (!this.isProtocolV2() && refresh.has('verification') && supportsProtocolV1OnekeyFeatures) {
|
|
1107
|
+
const { message } = await this.commands.typedCall('OnekeyGetFeatures', 'OnekeyFeatures');
|
|
1108
|
+
this.updateState(mapProtocolV1OnekeyFeaturesToState(message), 'device-info');
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
if (this.isProtocolV2()) {
|
|
1112
|
+
const refreshDeviceInfo =
|
|
1113
|
+
refresh.has('identity') || refresh.has('versions') || refresh.has('verification');
|
|
1114
|
+
if (refreshDeviceInfo && !initializedWithDeviceInfo) {
|
|
1115
|
+
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
1116
|
+
commands: this.commands,
|
|
1117
|
+
request: getProtocolV2DeviceInfoRequest(),
|
|
1118
|
+
});
|
|
1119
|
+
refreshedDeviceInfo = deviceInfo;
|
|
1120
|
+
if (!refresh.has('status')) {
|
|
1121
|
+
this.updateState(
|
|
1122
|
+
mapProtocolV2DeviceInfoToState(deviceInfo, this.state?.status.mode),
|
|
1123
|
+
'device-info'
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
if (refresh.has('status') && !initializedWithDeviceInfo) {
|
|
1129
|
+
const cachedMode = this.state?.status.mode;
|
|
1130
|
+
await this.probeProtocolV2RuntimeState(refreshedDeviceInfo, undefined, {
|
|
1131
|
+
// Loader firmware does not support DeviceStatusGet. Renegotiate ProtocolInfo
|
|
1132
|
+
// during an explicit refresh so a device rebooted into application firmware
|
|
1133
|
+
// can leave the cached loader state.
|
|
1134
|
+
forceRuntimeContextRefresh: cachedMode === 'bootloader' || cachedMode === 'romloader',
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
if (refresh.has('settings') && this.state?.status.mode === 'normal') {
|
|
1139
|
+
const { message } = await this.commands.typedCall(
|
|
1140
|
+
'DeviceSettingsGet',
|
|
1141
|
+
'DeviceSettings',
|
|
1142
|
+
{}
|
|
1143
|
+
);
|
|
1144
|
+
this.updateState(mapDeviceSettingsToState(message), 'settings-read');
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
if (!this.state) {
|
|
1149
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed);
|
|
1150
|
+
}
|
|
1151
|
+
return params.includeRaw ? cloneDeviceState(this.state) : createPublicDeviceState(this.state);
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
async refreshProtocolV2SettingsAfterMutation() {
|
|
1155
|
+
return this.getDeviceState({ refreshSections: ['status', 'settings'] });
|
|
1156
|
+
}
|
|
1157
|
+
|
|
847
1158
|
_updateFeatures(protoFeatures: PROTO.Features | Features, initSession?: boolean) {
|
|
848
|
-
const
|
|
1159
|
+
const previousDeviceId = this.getCurrentDeviceId();
|
|
849
1160
|
let feat =
|
|
850
1161
|
'protocol' in protoFeatures
|
|
851
1162
|
? protoFeatures
|
|
852
1163
|
: buildProtocolV1FeaturesPayload(protoFeatures, this.features);
|
|
853
1164
|
|
|
854
|
-
// GetFeatures doesn't return 'session_id'
|
|
855
|
-
if (this.features?.sessionId && !feat.sessionId) {
|
|
856
|
-
feat.sessionId = this.features.sessionId;
|
|
857
|
-
}
|
|
858
1165
|
feat.unlocked = feat.unlocked ?? true;
|
|
859
1166
|
|
|
860
1167
|
feat = fixFeaturesFirmwareVersion(feat);
|
|
861
1168
|
|
|
862
|
-
this.
|
|
863
|
-
|
|
864
|
-
if (previousCacheDeviceKey && nextCacheDeviceKey) {
|
|
865
|
-
deviceWalletSessionStore.migrateDeviceKey(previousCacheDeviceKey, nextCacheDeviceKey);
|
|
866
|
-
}
|
|
1169
|
+
this.updateState(mapFeaturesToState(feat), 'initialize');
|
|
1170
|
+
this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
|
|
867
1171
|
if (feat.deviceId && feat.sessionId) {
|
|
868
1172
|
this.setInternalState(feat.sessionId, initSession);
|
|
869
1173
|
}
|
|
870
|
-
this.featuresNeedsReload = false;
|
|
871
|
-
this.emit(DEVICE.FEATURES, this, feat);
|
|
872
1174
|
}
|
|
873
1175
|
|
|
874
|
-
|
|
875
|
-
const
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
1176
|
+
updateState(patch: DeviceStatePatch, source: DeviceStateUpdateSource) {
|
|
1177
|
+
const result = this.stateStore.update(patch, source);
|
|
1178
|
+
if (result.changedKeys.length === 0) return result.state;
|
|
1179
|
+
|
|
1180
|
+
const event: DeviceStateEvent = {
|
|
1181
|
+
connectId: this.getConnectId() ?? null,
|
|
1182
|
+
state: createPublicDeviceState(result.state),
|
|
1183
|
+
revision: result.revision,
|
|
1184
|
+
source,
|
|
1185
|
+
changedKeys: result.changedKeys,
|
|
1186
|
+
};
|
|
1187
|
+
Log.debug('Device state updated', {
|
|
1188
|
+
source,
|
|
1189
|
+
revision: result.revision,
|
|
1190
|
+
changedKeyCount: result.changedKeys.length,
|
|
1191
|
+
});
|
|
1192
|
+
this.emit(DEVICE.STATE, this, event);
|
|
1193
|
+
if (result.state.protocol === 'V1') {
|
|
1194
|
+
this.emit(DEVICE.FEATURES, this, projectFeatures(result.state));
|
|
1195
|
+
}
|
|
1196
|
+
return result.state;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
updateFeaturesPatch(patch: Partial<Features>, source: DeviceStateUpdateSource) {
|
|
1200
|
+
const currentFeatures = this.features;
|
|
1201
|
+
if (!currentFeatures) return undefined;
|
|
1202
|
+
|
|
1203
|
+
const features = mergeDeviceFeaturesPatch(currentFeatures, patch);
|
|
1204
|
+
if (features === currentFeatures) return currentFeatures;
|
|
1205
|
+
|
|
1206
|
+
const normalized = fixFeaturesFirmwareVersion(features);
|
|
1207
|
+
this.updateState(mapFeaturesToState(normalized), source);
|
|
1208
|
+
return this.features;
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
async ensureProtocolV2RuntimeContext(
|
|
1212
|
+
timeoutMs?: number,
|
|
1213
|
+
options?: { forceRefresh?: boolean }
|
|
1214
|
+
): Promise<ProtocolInfo> {
|
|
1215
|
+
const cachedProtocolInfo =
|
|
1216
|
+
options?.forceRefresh === true
|
|
1217
|
+
? undefined
|
|
1218
|
+
: this.protocolV2RuntimeContext ??
|
|
1219
|
+
(!this.protocolV2StateNeedsReload
|
|
1220
|
+
? this.state?.raw?.protocolV2ProtocolInfo ?? undefined
|
|
1221
|
+
: undefined);
|
|
1222
|
+
if (cachedProtocolInfo) {
|
|
1223
|
+
this.protocolV2RuntimeContext = cachedProtocolInfo;
|
|
1224
|
+
return cachedProtocolInfo;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
if (this.protocolV2RuntimeContextPromise) {
|
|
1228
|
+
return this.protocolV2RuntimeContextPromise;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
const requestToken = {};
|
|
1232
|
+
const pendingRequest = (async () => {
|
|
1233
|
+
const protocolInfo = await requestProtocolV2ProtocolInfo({
|
|
1234
|
+
commands: this.commands,
|
|
1235
|
+
timeoutMs,
|
|
1236
|
+
});
|
|
1237
|
+
if (this.protocolV2RuntimeContextRequestToken !== requestToken) {
|
|
1238
|
+
throw ERRORS.TypedError(
|
|
1239
|
+
HardwareErrorCode.DeviceInitializeFailed,
|
|
1240
|
+
'Protocol V2 runtime context was invalidated while loading.'
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
1243
|
+
this.protocolV2RuntimeContext = protocolInfo;
|
|
1244
|
+
return protocolInfo;
|
|
1245
|
+
})();
|
|
1246
|
+
this.protocolV2RuntimeContextRequestToken = requestToken;
|
|
1247
|
+
this.protocolV2RuntimeContextPromise = pendingRequest;
|
|
1248
|
+
|
|
1249
|
+
try {
|
|
1250
|
+
return await pendingRequest;
|
|
1251
|
+
} finally {
|
|
1252
|
+
if (this.protocolV2RuntimeContextPromise === pendingRequest) {
|
|
1253
|
+
this.protocolV2RuntimeContextPromise = undefined;
|
|
1254
|
+
}
|
|
1255
|
+
if (this.protocolV2RuntimeContextRequestToken === requestToken) {
|
|
1256
|
+
this.protocolV2RuntimeContextRequestToken = undefined;
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
async probeProtocolV2RuntimeState(
|
|
1262
|
+
deviceInfo?: ProtocolV2DeviceInfo,
|
|
1263
|
+
timeoutMs?: number,
|
|
1264
|
+
options?: {
|
|
1265
|
+
forceRuntimeContextRefresh?: boolean;
|
|
1266
|
+
}
|
|
1267
|
+
) {
|
|
1268
|
+
const protocolInfo = await this.ensureProtocolV2RuntimeContext(timeoutMs, {
|
|
1269
|
+
forceRefresh: options?.forceRuntimeContextRefresh,
|
|
1270
|
+
});
|
|
1271
|
+
const runtimeDeviceInfo = deviceInfo ?? this.state?.raw?.protocolV2DeviceInfo;
|
|
1272
|
+
const runtimeMode = getProtocolV2RuntimeMode(protocolInfo, runtimeDeviceInfo);
|
|
1273
|
+
const legacyProtocolInfo = isLegacyProtocolV2ProtocolInfo(protocolInfo);
|
|
1274
|
+
const protocolV2DeviceType = runtimeDeviceInfo
|
|
1275
|
+
? resolveProtocolV2DeviceIdentity(runtimeDeviceInfo.hw?.Device_type).deviceType
|
|
1276
|
+
: this.getCurrentDeviceType();
|
|
1277
|
+
if (
|
|
1278
|
+
runtimeMode === 'romloader' &&
|
|
1279
|
+
protocolV2DeviceType !== EDeviceType.Pro2 &&
|
|
1280
|
+
protocolV2DeviceType !== EDeviceType.Neo
|
|
1281
|
+
) {
|
|
1282
|
+
throw ERRORS.TypedError(
|
|
1283
|
+
HardwareErrorCode.DeviceInitializeFailed,
|
|
1284
|
+
'Protocol V2 romloader mode is only supported for Pro2 and Neo.'
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
const deviceStatusSupported =
|
|
1288
|
+
legacyProtocolInfo ||
|
|
1289
|
+
supportsProtocolV2Message(protocolInfo, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE);
|
|
1290
|
+
|
|
1291
|
+
if (runtimeMode === 'bootloader' || runtimeMode === 'romloader') {
|
|
1292
|
+
return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
if (!deviceStatusSupported) {
|
|
1296
|
+
if (runtimeMode === 'normal') {
|
|
1297
|
+
return this.updateProtocolV2Features(deviceInfo, null, runtimeMode, protocolInfo);
|
|
1298
|
+
}
|
|
1299
|
+
throw ERRORS.TypedError(
|
|
1300
|
+
HardwareErrorCode.DeviceInitializeFailed,
|
|
1301
|
+
`Unknown Protocol V2 build fingerprint without DeviceStatusGet capability: ${protocolInfo.build_fingerprint}`
|
|
1302
|
+
);
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
let deviceStatus: DeviceStatus;
|
|
1306
|
+
try {
|
|
1307
|
+
deviceStatus = await requestProtocolV2DeviceStatus({
|
|
1308
|
+
commands: this.commands,
|
|
1309
|
+
timeoutMs,
|
|
1310
|
+
});
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
if (runtimeMode === undefined && isProtocolV2DeviceStatusUnsupportedError(error)) {
|
|
1313
|
+
return this.updateProtocolV2Features(deviceInfo, null, 'bootloader', protocolInfo);
|
|
1314
|
+
}
|
|
1315
|
+
throw error;
|
|
1316
|
+
}
|
|
1317
|
+
return this.updateProtocolV2Features(deviceInfo, deviceStatus, 'normal', protocolInfo);
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
updateProtocolV2Features(
|
|
1321
|
+
deviceInfo?: ProtocolV2DeviceInfo,
|
|
1322
|
+
deviceStatus?: DeviceStatus | null,
|
|
1323
|
+
runtimeMode?: ProtocolV2RuntimeMode,
|
|
1324
|
+
protocolInfo?: ProtocolInfo
|
|
1325
|
+
) {
|
|
1326
|
+
const previousDeviceId = this.getCurrentDeviceId();
|
|
1327
|
+
const resolvedMode = runtimeMode ?? (deviceStatus ? 'normal' : this.state?.status.mode);
|
|
1328
|
+
if (deviceInfo) {
|
|
1329
|
+
this.updateState(mapProtocolV2DeviceInfoToState(deviceInfo, resolvedMode), 'device-info');
|
|
1330
|
+
}
|
|
1331
|
+
if (protocolInfo) {
|
|
1332
|
+
this.updateState({ raw: { protocolV2ProtocolInfo: protocolInfo } }, 'device-info');
|
|
1333
|
+
}
|
|
1334
|
+
if (deviceStatus) {
|
|
1335
|
+
this.updateState(mapProtocolV2DeviceStatusToState(deviceStatus), 'device-status');
|
|
883
1336
|
}
|
|
884
|
-
this.
|
|
885
|
-
this.
|
|
886
|
-
return features;
|
|
1337
|
+
this.reconcileSessionCacheDeviceIdentity(previousDeviceId);
|
|
1338
|
+
return this.features as Features;
|
|
887
1339
|
}
|
|
888
1340
|
|
|
889
1341
|
updateProtocolV2Status(status: DeviceStatus) {
|
|
890
|
-
const previousDeviceInfo = this.
|
|
891
|
-
const previousStatus =
|
|
892
|
-
return this.updateProtocolV2Features({
|
|
893
|
-
...
|
|
894
|
-
|
|
895
|
-
status: {
|
|
896
|
-
...previousStatus,
|
|
897
|
-
...status,
|
|
898
|
-
},
|
|
1342
|
+
const previousDeviceInfo = this.state?.raw?.protocolV2DeviceInfo;
|
|
1343
|
+
const previousStatus = this.state?.raw?.protocolV2DeviceStatus;
|
|
1344
|
+
return this.updateProtocolV2Features(previousDeviceInfo, {
|
|
1345
|
+
...previousStatus,
|
|
1346
|
+
...status,
|
|
899
1347
|
});
|
|
900
1348
|
}
|
|
901
1349
|
|
|
1350
|
+
private invalidateProtocolV2RuntimeState() {
|
|
1351
|
+
if (!this.isProtocolV2()) return;
|
|
1352
|
+
this.protocolV2StateNeedsReload = true;
|
|
1353
|
+
this.protocolV2RuntimeContext = undefined;
|
|
1354
|
+
this.protocolV2RuntimeContextPromise = undefined;
|
|
1355
|
+
this.protocolV2RuntimeContextRequestToken = undefined;
|
|
1356
|
+
this.clearPreInitialized();
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
markTransportDisconnected() {
|
|
1360
|
+
this.deviceAcquired = false;
|
|
1361
|
+
this.invalidateProtocolV2RuntimeState();
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
invalidateAfterWipe() {
|
|
1365
|
+
const deviceId = this.getCurrentDeviceId();
|
|
1366
|
+
if (deviceId) {
|
|
1367
|
+
deviceWalletSessionStore.deleteDevice(deviceId);
|
|
1368
|
+
}
|
|
1369
|
+
if (this.isProtocolV2()) {
|
|
1370
|
+
if (this.originalDescriptor.path !== deviceId) {
|
|
1371
|
+
deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
|
|
1372
|
+
}
|
|
1373
|
+
this.invalidateProtocolV2RuntimeState();
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
this.passphraseState = undefined;
|
|
1377
|
+
this.stateStore = new DeviceStateStore();
|
|
1378
|
+
this.clearPreInitialized();
|
|
1379
|
+
this.needReloadDevice = true;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
markProtocolV2Reboot(rebootType: DeviceRebootType) {
|
|
1383
|
+
if (!this.isProtocolV2()) return;
|
|
1384
|
+
|
|
1385
|
+
this.invalidateProtocolV2RuntimeState();
|
|
1386
|
+
let loaderMode: 'bootloader' | 'romloader' | undefined;
|
|
1387
|
+
if (rebootType === DeviceRebootType.Bootloader) {
|
|
1388
|
+
loaderMode = 'bootloader';
|
|
1389
|
+
} else if (rebootType === DeviceRebootType.Romloader) {
|
|
1390
|
+
loaderMode = 'romloader';
|
|
1391
|
+
}
|
|
1392
|
+
if (loaderMode) {
|
|
1393
|
+
this.updateState(
|
|
1394
|
+
{
|
|
1395
|
+
identity: { deviceId: null },
|
|
1396
|
+
status: {
|
|
1397
|
+
mode: loaderMode,
|
|
1398
|
+
initialized: null,
|
|
1399
|
+
unlocked: null,
|
|
1400
|
+
firmwarePresent: null,
|
|
1401
|
+
backupRequired: null,
|
|
1402
|
+
noBackup: null,
|
|
1403
|
+
unfinishedBackup: null,
|
|
1404
|
+
recoveryMode: null,
|
|
1405
|
+
passphraseProtection: null,
|
|
1406
|
+
pinProtection: null,
|
|
1407
|
+
attachToPinEnabled: null,
|
|
1408
|
+
unlockedAttachPin: null,
|
|
1409
|
+
},
|
|
1410
|
+
raw: { protocolV2ProtocolInfo: null, protocolV2DeviceStatus: null },
|
|
1411
|
+
},
|
|
1412
|
+
'transport-reconnect'
|
|
1413
|
+
);
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
this.updateState(
|
|
1418
|
+
{
|
|
1419
|
+
status: { mode: 'normal', unlocked: null },
|
|
1420
|
+
raw: { protocolV2ProtocolInfo: null, protocolV2DeviceStatus: null },
|
|
1421
|
+
},
|
|
1422
|
+
'transport-reconnect'
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
|
|
902
1426
|
/**
|
|
903
1427
|
* 暂时只在 acquire 后更新 Session ID
|
|
904
1428
|
* 后续看是否有需要依据 listen 返回结果更新
|
|
@@ -917,8 +1441,7 @@ export class Device extends EventEmitter {
|
|
|
917
1441
|
}
|
|
918
1442
|
|
|
919
1443
|
if (forceUpdate) {
|
|
920
|
-
//
|
|
921
|
-
// 不能让覆盖丢掉已探测的协议结果。
|
|
1444
|
+
// Enumerated descriptors may omit protocolType, so preserve an actively probed value.
|
|
922
1445
|
this.originalDescriptor = {
|
|
923
1446
|
...descriptor,
|
|
924
1447
|
protocolType: descriptor.protocolType ?? this.originalDescriptor.protocolType,
|
|
@@ -933,6 +1456,10 @@ export class Device extends EventEmitter {
|
|
|
933
1456
|
if (device.features) {
|
|
934
1457
|
this._updateFeatures(device.features);
|
|
935
1458
|
}
|
|
1459
|
+
// Adopting another Device instance's command channel also crosses an active
|
|
1460
|
+
// link boundary. Renegotiate runtime metadata on that channel instead of
|
|
1461
|
+
// retaining ProtocolInfo from the previous instance/session.
|
|
1462
|
+
this.invalidateProtocolV2RuntimeState();
|
|
936
1463
|
}
|
|
937
1464
|
|
|
938
1465
|
async run(fn?: () => Promise<void>, options?: RunOptions) {
|
|
@@ -941,21 +1468,54 @@ export class Device extends EventEmitter {
|
|
|
941
1468
|
Log.debug('[Device] run error:', 'Device is running, but will cancel previous operate');
|
|
942
1469
|
}
|
|
943
1470
|
|
|
1471
|
+
this.beginConnectionAttempt();
|
|
944
1472
|
options = parseRunOptions(options);
|
|
945
1473
|
|
|
946
|
-
|
|
947
|
-
|
|
1474
|
+
const runPromise = createDeferred<void>();
|
|
1475
|
+
this.runPromise = runPromise;
|
|
1476
|
+
const cleanupPromise = this._runInner(fn, options, runPromise).catch(error => {
|
|
1477
|
+
if (this.runPromise === runPromise) {
|
|
1478
|
+
this.runPromise = null;
|
|
1479
|
+
}
|
|
1480
|
+
runPromise.reject(error);
|
|
1481
|
+
});
|
|
1482
|
+
this.runCleanupPromise = cleanupPromise;
|
|
1483
|
+
cleanupPromise
|
|
1484
|
+
.finally(() => {
|
|
1485
|
+
if (this.runCleanupPromise === cleanupPromise) {
|
|
1486
|
+
this.runCleanupPromise = undefined;
|
|
1487
|
+
}
|
|
1488
|
+
})
|
|
1489
|
+
.catch(() => undefined);
|
|
1490
|
+
return runPromise.promise;
|
|
948
1491
|
}
|
|
949
1492
|
|
|
950
|
-
async _runInner<T>(
|
|
951
|
-
|
|
952
|
-
|
|
1493
|
+
async _runInner<T>(
|
|
1494
|
+
fn: (() => Promise<T>) | undefined,
|
|
1495
|
+
options: RunOptions,
|
|
1496
|
+
runPromise: Deferred<void>
|
|
1497
|
+
) {
|
|
1498
|
+
const clearRunPromise = () => {
|
|
1499
|
+
if (this.runPromise === runPromise) {
|
|
1500
|
+
this.runPromise = null;
|
|
1501
|
+
}
|
|
1502
|
+
};
|
|
1503
|
+
|
|
1504
|
+
const env = DataManager.getSettings('env');
|
|
1505
|
+
if (options.forceProtocolDetection && env !== 'react-native' && this.isUsedHere()) {
|
|
1506
|
+
await this.release();
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
if (options.forceProtocolDetection || !this.isUsedHere() || this.commands.disposed) {
|
|
953
1510
|
if (env !== 'react-native') {
|
|
954
1511
|
try {
|
|
955
|
-
await this.acquire(options.connectProtocol
|
|
1512
|
+
await this.acquire(options.connectProtocol, {
|
|
1513
|
+
forceProtocolDetection: options.forceProtocolDetection,
|
|
1514
|
+
});
|
|
956
1515
|
} catch (error) {
|
|
957
|
-
|
|
958
|
-
|
|
1516
|
+
clearRunPromise();
|
|
1517
|
+
runPromise.reject(error);
|
|
1518
|
+
return;
|
|
959
1519
|
}
|
|
960
1520
|
|
|
961
1521
|
try {
|
|
@@ -965,16 +1525,19 @@ export class Device extends EventEmitter {
|
|
|
965
1525
|
}
|
|
966
1526
|
}
|
|
967
1527
|
} catch (error) {
|
|
968
|
-
this.
|
|
1528
|
+
await this.release();
|
|
1529
|
+
clearRunPromise();
|
|
969
1530
|
if (error instanceof HardwareError) {
|
|
970
|
-
|
|
1531
|
+
runPromise.reject(error);
|
|
1532
|
+
return;
|
|
971
1533
|
}
|
|
972
|
-
|
|
1534
|
+
runPromise.reject(
|
|
973
1535
|
ERRORS.TypedError(
|
|
974
1536
|
HardwareErrorCode.DeviceInitializeFailed,
|
|
975
1537
|
`Initialize failed: ${error.message as string}, code: ${error.code as string}`
|
|
976
1538
|
)
|
|
977
1539
|
);
|
|
1540
|
+
return;
|
|
978
1541
|
}
|
|
979
1542
|
} else if (env === 'react-native') {
|
|
980
1543
|
// TODO: implement react-native acquire
|
|
@@ -993,9 +1556,7 @@ export class Device extends EventEmitter {
|
|
|
993
1556
|
try {
|
|
994
1557
|
await fn();
|
|
995
1558
|
} catch (e) {
|
|
996
|
-
|
|
997
|
-
this.runPromise.reject(e);
|
|
998
|
-
}
|
|
1559
|
+
runPromise.reject(e);
|
|
999
1560
|
|
|
1000
1561
|
if (
|
|
1001
1562
|
e instanceof HardwareError &&
|
|
@@ -1008,7 +1569,7 @@ export class Device extends EventEmitter {
|
|
|
1008
1569
|
Log.debug(`error code ${e.errorCode} release device, mainId: ${this.mainId}`);
|
|
1009
1570
|
}
|
|
1010
1571
|
|
|
1011
|
-
|
|
1572
|
+
clearRunPromise();
|
|
1012
1573
|
return;
|
|
1013
1574
|
}
|
|
1014
1575
|
}
|
|
@@ -1022,11 +1583,8 @@ export class Device extends EventEmitter {
|
|
|
1022
1583
|
Log.debug('release device, mainId: ', this.mainId);
|
|
1023
1584
|
}
|
|
1024
1585
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
this.runPromise = null;
|
|
1586
|
+
runPromise.resolve();
|
|
1587
|
+
clearRunPromise();
|
|
1030
1588
|
}
|
|
1031
1589
|
|
|
1032
1590
|
async interruptionFromOutside() {
|
|
@@ -1040,13 +1598,32 @@ export class Device extends EventEmitter {
|
|
|
1040
1598
|
|
|
1041
1599
|
async interruptionFromUser() {
|
|
1042
1600
|
const error = ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
|
|
1043
|
-
|
|
1601
|
+
this.interruptedAttempt = this.connectionAttempt;
|
|
1602
|
+
const cleanupPromise = this.runCleanupPromise;
|
|
1603
|
+
const { cancelableAction } = this;
|
|
1604
|
+
if (cancelableAction) {
|
|
1605
|
+
await cancelableAction(error);
|
|
1606
|
+
} else if (this.shouldSendFallbackProtocolCancel()) {
|
|
1607
|
+
await this.commands?.cancelDevice?.().catch(cancelError => {
|
|
1608
|
+
Log.debug('Protocol V2 fallback cancel error', cancelError);
|
|
1609
|
+
});
|
|
1610
|
+
} else if (!this.hasDeviceAcquire()) {
|
|
1611
|
+
// Pairing / connect-native / probe: drop the physical link only.
|
|
1612
|
+
// Never acquire or send protocol Cancel just to abort setup.
|
|
1613
|
+
if (this.mainId && this.deviceConnector?.disconnect) {
|
|
1614
|
+
await this.deviceConnector.disconnect(this.mainId).catch(disconnectError => {
|
|
1615
|
+
Log.debug('Ignored disconnect during user cancel without acquire', disconnectError);
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
this.markTransportDisconnected();
|
|
1619
|
+
}
|
|
1044
1620
|
await this.commands?.cancel();
|
|
1045
1621
|
|
|
1046
1622
|
if (this.runPromise) {
|
|
1047
1623
|
this.runPromise.reject(error);
|
|
1048
1624
|
this.runPromise = null;
|
|
1049
1625
|
}
|
|
1626
|
+
await cleanupPromise?.catch(() => undefined);
|
|
1050
1627
|
}
|
|
1051
1628
|
|
|
1052
1629
|
setCancelableAction(callback: (err?: Error) => Promise<unknown>) {
|
|
@@ -1065,39 +1642,81 @@ export class Device extends EventEmitter {
|
|
|
1065
1642
|
}
|
|
1066
1643
|
|
|
1067
1644
|
getMode() {
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1645
|
+
switch (this.state?.status.mode) {
|
|
1646
|
+
case 'bootloader':
|
|
1647
|
+
case 'romloader':
|
|
1648
|
+
return EOneKeyDeviceMode.bootloader;
|
|
1649
|
+
case 'notInitialized':
|
|
1650
|
+
return EOneKeyDeviceMode.notInitialized;
|
|
1651
|
+
case 'backupMode':
|
|
1652
|
+
return EOneKeyDeviceMode.backupMode;
|
|
1653
|
+
case 'normal':
|
|
1654
|
+
return EOneKeyDeviceMode.normal;
|
|
1655
|
+
default:
|
|
1656
|
+
break;
|
|
1071
1657
|
}
|
|
1072
1658
|
|
|
1073
|
-
if (!this.features?.initialized) {
|
|
1074
|
-
// not initialized
|
|
1075
|
-
return EOneKeyDeviceMode.notInitialized;
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
if (this.features?.noBackup) {
|
|
1079
|
-
// backup mode
|
|
1080
|
-
return EOneKeyDeviceMode.backupMode;
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
// normal mode
|
|
1084
1659
|
return EOneKeyDeviceMode.normal;
|
|
1085
1660
|
}
|
|
1086
1661
|
|
|
1662
|
+
getStatus() {
|
|
1663
|
+
if (this.isUsedElsewhere()) return 'occupied' as const;
|
|
1664
|
+
if (this.isUsedHere()) return 'used' as const;
|
|
1665
|
+
return 'available' as const;
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1087
1668
|
getFirmwareVersion() {
|
|
1088
|
-
if (!this.
|
|
1089
|
-
return
|
|
1669
|
+
if (!this.state) return null;
|
|
1670
|
+
return parseDeviceVersion(this.state.versions.firmware);
|
|
1090
1671
|
}
|
|
1091
1672
|
|
|
1092
1673
|
getBLEFirmwareVersion() {
|
|
1093
|
-
if (!this.
|
|
1094
|
-
return
|
|
1674
|
+
if (!this.state) return null;
|
|
1675
|
+
return parseDeviceVersion(this.state.versions.ble);
|
|
1095
1676
|
}
|
|
1096
1677
|
|
|
1097
1678
|
isUsed() {
|
|
1098
1679
|
return typeof this.originalDescriptor.session === 'string';
|
|
1099
1680
|
}
|
|
1100
1681
|
|
|
1682
|
+
beginConnectionAttempt() {
|
|
1683
|
+
this.connectionAttempt += 1;
|
|
1684
|
+
return this.connectionAttempt;
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
wasInterruptedByUser() {
|
|
1688
|
+
return (
|
|
1689
|
+
typeof this.interruptedAttempt === 'number' &&
|
|
1690
|
+
this.interruptedAttempt === this.connectionAttempt
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
private throwIfInterruptedByUser() {
|
|
1695
|
+
if (this.wasInterruptedByUser()) {
|
|
1696
|
+
throw ERRORS.TypedError(HardwareErrorCode.DeviceInterruptedFromUser);
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
/**
|
|
1701
|
+
* Protocol Cancel is only for an acquired session that is already in a
|
|
1702
|
+
* user-facing prompt. Connect, probe and initialize must not send Cancel
|
|
1703
|
+
* and must not re-acquire just to deliver one.
|
|
1704
|
+
*/
|
|
1705
|
+
private shouldSendFallbackProtocolCancel() {
|
|
1706
|
+
if (!this.hasDeviceAcquire() || !this.isProtocolV2()) {
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1709
|
+
if (!this.hasOpenProtocolV2UiInteraction()) {
|
|
1710
|
+
return false;
|
|
1711
|
+
}
|
|
1712
|
+
const env = DataManager.getSettings('env');
|
|
1713
|
+
return (
|
|
1714
|
+
DataManager.isBleConnect(env) ||
|
|
1715
|
+
DataManager.isBrowserWebUsb(env) ||
|
|
1716
|
+
DataManager.isDesktopWebUsb(env)
|
|
1717
|
+
);
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1101
1720
|
hasDeviceAcquire() {
|
|
1102
1721
|
const env = DataManager.getSettings('env');
|
|
1103
1722
|
if (DataManager.isBleConnect(env)) {
|
|
@@ -1109,7 +1728,7 @@ export class Device extends EventEmitter {
|
|
|
1109
1728
|
isUsedHere() {
|
|
1110
1729
|
const env = DataManager.getSettings('env');
|
|
1111
1730
|
if (DataManager.isBleConnect(env)) {
|
|
1112
|
-
return
|
|
1731
|
+
return this.deviceAcquired;
|
|
1113
1732
|
}
|
|
1114
1733
|
return this.isUsed() && this.originalDescriptor.session === this.mainId;
|
|
1115
1734
|
}
|
|
@@ -1119,19 +1738,32 @@ export class Device extends EventEmitter {
|
|
|
1119
1738
|
}
|
|
1120
1739
|
|
|
1121
1740
|
isBootloader() {
|
|
1122
|
-
|
|
1741
|
+
if (!this.state) return undefined;
|
|
1742
|
+
return this.state.status.mode === 'bootloader';
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
isRomloader() {
|
|
1746
|
+
if (!this.state) return undefined;
|
|
1747
|
+
return (
|
|
1748
|
+
this.isProtocolV2() &&
|
|
1749
|
+
(this.getCurrentDeviceType() === EDeviceType.Pro2 ||
|
|
1750
|
+
this.getCurrentDeviceType() === EDeviceType.Neo) &&
|
|
1751
|
+
this.state.status.mode === 'romloader'
|
|
1752
|
+
);
|
|
1123
1753
|
}
|
|
1124
1754
|
|
|
1125
1755
|
isInitialized() {
|
|
1126
|
-
|
|
1756
|
+
if (!this.state) return undefined;
|
|
1757
|
+
return this.state.status.initialized === true;
|
|
1127
1758
|
}
|
|
1128
1759
|
|
|
1129
1760
|
isSeedless() {
|
|
1130
|
-
|
|
1761
|
+
if (!this.state) return undefined;
|
|
1762
|
+
return this.state.status.noBackup === true;
|
|
1131
1763
|
}
|
|
1132
1764
|
|
|
1133
1765
|
isUnacquired(): boolean {
|
|
1134
|
-
return this.
|
|
1766
|
+
return this.state === undefined;
|
|
1135
1767
|
}
|
|
1136
1768
|
|
|
1137
1769
|
hasUnexpectedMode(allow: string[], require: string[]) {
|
|
@@ -1161,8 +1793,9 @@ export class Device extends EventEmitter {
|
|
|
1161
1793
|
const isModeT =
|
|
1162
1794
|
deviceType === EDeviceType.Touch ||
|
|
1163
1795
|
deviceType === EDeviceType.Pro ||
|
|
1164
|
-
deviceType === EDeviceType.Pro2
|
|
1165
|
-
|
|
1796
|
+
deviceType === EDeviceType.Pro2 ||
|
|
1797
|
+
deviceType === EDeviceType.Neo;
|
|
1798
|
+
const unlocked = this.state?.status.unlocked;
|
|
1166
1799
|
const preCheckTouch = isModeT && unlocked === false;
|
|
1167
1800
|
const passphraseProtection = this.getCurrentPassphraseProtection();
|
|
1168
1801
|
|
|
@@ -1175,11 +1808,91 @@ export class Device extends EventEmitter {
|
|
|
1175
1808
|
|
|
1176
1809
|
async lockDevice(): Promise<Success> {
|
|
1177
1810
|
const res = await this.commands.typedCall('LockDevice', 'Success', {});
|
|
1811
|
+
this.updateState({ status: { unlocked: false } }, 'lock');
|
|
1178
1812
|
return res.message;
|
|
1179
1813
|
}
|
|
1180
1814
|
|
|
1815
|
+
beginProtocolV2UiInteraction() {
|
|
1816
|
+
if (!this.isProtocolV2()) return;
|
|
1817
|
+
this.protocolV2UiInteraction = {
|
|
1818
|
+
interactionId: `${this.instanceId}:${Date.now()}:${++this.protocolV2UiInteractionCounter}`,
|
|
1819
|
+
phaseCounter: 0,
|
|
1820
|
+
sequence: 0,
|
|
1821
|
+
opened: false,
|
|
1822
|
+
};
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
createProtocolV2UiPhaseMetadata(
|
|
1826
|
+
phase: HardwareUiInteractionMeta['phase'],
|
|
1827
|
+
transition: HardwareUiInteractionMeta['transition'],
|
|
1828
|
+
options?: {
|
|
1829
|
+
phaseId?: string;
|
|
1830
|
+
outcome?: HardwareUiInteractionMeta['outcome'];
|
|
1831
|
+
}
|
|
1832
|
+
): HardwareUiInteractionMeta | undefined {
|
|
1833
|
+
if (!this.isProtocolV2()) return undefined;
|
|
1834
|
+
if (!this.protocolV2UiInteraction) this.beginProtocolV2UiInteraction();
|
|
1835
|
+
|
|
1836
|
+
const interaction = this.protocolV2UiInteraction;
|
|
1837
|
+
if (!interaction) return undefined;
|
|
1838
|
+
const phaseId =
|
|
1839
|
+
options?.phaseId ?? `${interaction.interactionId}:phase-${++interaction.phaseCounter}`;
|
|
1840
|
+
interaction.opened = true;
|
|
1841
|
+
interaction.sequence += 1;
|
|
1842
|
+
|
|
1843
|
+
return {
|
|
1844
|
+
interactionId: interaction.interactionId,
|
|
1845
|
+
phaseId,
|
|
1846
|
+
sequence: interaction.sequence,
|
|
1847
|
+
phase,
|
|
1848
|
+
transition,
|
|
1849
|
+
...(options?.outcome ? { outcome: options.outcome } : {}),
|
|
1850
|
+
protocol: 'V2',
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
completeProtocolV2UiPhase(
|
|
1855
|
+
phase: HardwareUiInteractionMeta,
|
|
1856
|
+
outcome: HardwareUiInteractionMeta['outcome'] = 'succeeded'
|
|
1857
|
+
) {
|
|
1858
|
+
return this.createProtocolV2UiPhaseMetadata(phase.phase, 'complete', {
|
|
1859
|
+
phaseId: phase.phaseId,
|
|
1860
|
+
outcome,
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
finishProtocolV2UiInteraction(
|
|
1865
|
+
outcome?: HardwareUiInteractionMeta['outcome'],
|
|
1866
|
+
options?: { ensureMetadata?: boolean }
|
|
1867
|
+
) {
|
|
1868
|
+
const interaction = this.protocolV2UiInteraction;
|
|
1869
|
+
if (!interaction || (!interaction.opened && !options?.ensureMetadata)) {
|
|
1870
|
+
this.protocolV2UiInteraction = undefined;
|
|
1871
|
+
return undefined;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
const phaseId = `${interaction.interactionId}:phase-${Math.max(interaction.phaseCounter, 1)}`;
|
|
1875
|
+
interaction.opened = true;
|
|
1876
|
+
interaction.sequence += 1;
|
|
1877
|
+
const metadata: HardwareUiInteractionMeta = {
|
|
1878
|
+
interactionId: interaction.interactionId,
|
|
1879
|
+
phaseId,
|
|
1880
|
+
sequence: interaction.sequence,
|
|
1881
|
+
phase: 'processing',
|
|
1882
|
+
transition: 'finish',
|
|
1883
|
+
outcome: outcome ?? 'succeeded',
|
|
1884
|
+
protocol: 'V2',
|
|
1885
|
+
};
|
|
1886
|
+
this.protocolV2UiInteraction = undefined;
|
|
1887
|
+
return metadata;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
hasOpenProtocolV2UiInteraction() {
|
|
1891
|
+
return this.protocolV2UiInteraction?.opened === true;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1181
1894
|
supportUnlockVersionRange(): DeviceFirmwareRange {
|
|
1182
|
-
//
|
|
1895
|
+
// This range applies to Protocol V1 Pro devices; Pro2 has a dedicated unlock flow.
|
|
1183
1896
|
return {
|
|
1184
1897
|
pro: {
|
|
1185
1898
|
min: '4.15.0',
|
|
@@ -1187,10 +1900,33 @@ export class Device extends EventEmitter {
|
|
|
1187
1900
|
};
|
|
1188
1901
|
}
|
|
1189
1902
|
|
|
1190
|
-
async unlockDevice(
|
|
1903
|
+
async unlockDevice(
|
|
1904
|
+
pinType?: DeviceSessionPinType,
|
|
1905
|
+
options?: ProtocolV2UiEventMetadata & { emitUiEvent?: boolean }
|
|
1906
|
+
) {
|
|
1191
1907
|
if (this.isProtocolV2()) {
|
|
1908
|
+
const requestedPinType = pinType ?? DeviceSessionPinType.Main;
|
|
1909
|
+
const interaction =
|
|
1910
|
+
options?.interaction ??
|
|
1911
|
+
(options?.emitUiEvent === false
|
|
1912
|
+
? undefined
|
|
1913
|
+
: this.createProtocolV2UiPhaseMetadata('pin', 'start'));
|
|
1914
|
+
if (options?.emitUiEvent !== false) {
|
|
1915
|
+
this.emit(DEVICE.PIN_ON_DEVICE, this, requestedPinType, {
|
|
1916
|
+
source: options?.source ?? 'unlock-coordinator',
|
|
1917
|
+
reason: options?.reason ?? 'device-unlock',
|
|
1918
|
+
deviceOnly: options?.deviceOnly ?? true,
|
|
1919
|
+
completion: options?.completion,
|
|
1920
|
+
method: options?.method,
|
|
1921
|
+
page: options?.page,
|
|
1922
|
+
operation: options?.operation,
|
|
1923
|
+
interaction: options?.interaction ?? interaction,
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1192
1926
|
try {
|
|
1193
|
-
await this.commands.typedCall('DeviceSessionAskPin', 'Success'
|
|
1927
|
+
await this.commands.typedCall('DeviceSessionAskPin', 'Success', {
|
|
1928
|
+
type: requestedPinType,
|
|
1929
|
+
});
|
|
1194
1930
|
} catch (error) {
|
|
1195
1931
|
const errorText =
|
|
1196
1932
|
error instanceof Error
|
|
@@ -1202,11 +1938,12 @@ export class Device extends EventEmitter {
|
|
|
1202
1938
|
throw error;
|
|
1203
1939
|
}
|
|
1204
1940
|
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1941
|
+
const completion = interaction ? this.completeProtocolV2UiPhase(interaction) : undefined;
|
|
1942
|
+
if (completion) {
|
|
1943
|
+
this.emit(DEVICE.PIN_ON_DEVICE_COMPLETE, this, completion);
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
const status = await requestProtocolV2DeviceStatus({ commands: this.commands });
|
|
1210
1947
|
return this.updateProtocolV2Status(status);
|
|
1211
1948
|
}
|
|
1212
1949
|
|
|
@@ -1215,8 +1952,7 @@ export class Device extends EventEmitter {
|
|
|
1215
1952
|
type => this.supportUnlockVersionRange()[type]
|
|
1216
1953
|
);
|
|
1217
1954
|
|
|
1218
|
-
const supportAttachPinCapability =
|
|
1219
|
-
this.features,
|
|
1955
|
+
const supportAttachPinCapability = this.state?.capabilities.includes(
|
|
1220
1956
|
Enum_Capability.Capability_AttachToPin
|
|
1221
1957
|
);
|
|
1222
1958
|
const supportUnlock =
|
|
@@ -1227,12 +1963,21 @@ export class Device extends EventEmitter {
|
|
|
1227
1963
|
|
|
1228
1964
|
if (supportUnlock) {
|
|
1229
1965
|
const res = await this.commands.typedCall('UnLockDevice', 'UnLockDeviceResponse');
|
|
1230
|
-
if (this.
|
|
1231
|
-
this.
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1966
|
+
if (this.state) {
|
|
1967
|
+
this.updateState(
|
|
1968
|
+
{
|
|
1969
|
+
status: {
|
|
1970
|
+
unlocked: res.message.unlocked == null ? null : res.message.unlocked,
|
|
1971
|
+
unlockedAttachPin:
|
|
1972
|
+
res.message.unlocked_attach_pin == null ? null : res.message.unlocked_attach_pin,
|
|
1973
|
+
passphraseProtection:
|
|
1974
|
+
res.message.passphrase_protection == null
|
|
1975
|
+
? null
|
|
1976
|
+
: res.message.passphrase_protection,
|
|
1977
|
+
},
|
|
1978
|
+
},
|
|
1979
|
+
'unlock'
|
|
1980
|
+
);
|
|
1236
1981
|
|
|
1237
1982
|
return Promise.resolve(this.features);
|
|
1238
1983
|
}
|
|
@@ -1259,25 +2004,34 @@ export class Device extends EventEmitter {
|
|
|
1259
2004
|
async checkPassphraseStateSafety(
|
|
1260
2005
|
passphraseState?: string,
|
|
1261
2006
|
useEmptyPassphrase?: boolean,
|
|
1262
|
-
skipPassphraseCheck?: boolean
|
|
2007
|
+
skipPassphraseCheck?: boolean,
|
|
2008
|
+
deriveCardano?: boolean
|
|
1263
2009
|
) {
|
|
1264
2010
|
if (this.isUnacquired()) return false;
|
|
1265
2011
|
|
|
2012
|
+
const expectedPassphraseState = useEmptyPassphrase ? undefined : passphraseState;
|
|
1266
2013
|
const { passphraseState: newPassphraseState, unlockedAttachPin } =
|
|
1267
2014
|
await getPassphraseStateWithRefreshDeviceInfo(this, {
|
|
1268
|
-
expectPassphraseState:
|
|
2015
|
+
expectPassphraseState: expectedPassphraseState,
|
|
1269
2016
|
onlyMainPin: useEmptyPassphrase,
|
|
2017
|
+
deriveCardano,
|
|
2018
|
+
rejectAttachPinForMainWallet: useEmptyPassphrase === true,
|
|
1270
2019
|
});
|
|
1271
2020
|
|
|
1272
2021
|
// Main wallet and unlock Attach Pin, throw safe error
|
|
1273
2022
|
const mainWalletUseAttachPin = unlockedAttachPin && useEmptyPassphrase;
|
|
1274
2023
|
const useErrorAttachPin =
|
|
1275
|
-
unlockedAttachPin &&
|
|
1276
|
-
|
|
2024
|
+
unlockedAttachPin &&
|
|
2025
|
+
expectedPassphraseState &&
|
|
2026
|
+
expectedPassphraseState !== newPassphraseState;
|
|
2027
|
+
const passphraseStateMismatch =
|
|
2028
|
+
!!expectedPassphraseState && expectedPassphraseState !== newPassphraseState;
|
|
1277
2029
|
|
|
1278
2030
|
Log.debug('Check passphrase state safety: ', {
|
|
1279
|
-
|
|
1280
|
-
newPassphraseState,
|
|
2031
|
+
hasExpectedPassphraseState: Boolean(expectedPassphraseState),
|
|
2032
|
+
hasNewPassphraseState: Boolean(newPassphraseState),
|
|
2033
|
+
passphraseStateMatches:
|
|
2034
|
+
Boolean(expectedPassphraseState) && expectedPassphraseState === newPassphraseState,
|
|
1281
2035
|
unlockedAttachPin,
|
|
1282
2036
|
useEmptyPassphrase,
|
|
1283
2037
|
});
|