@onekeyfe/hd-core 1.1.27 → 1.2.0-alpha.0
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__/evmLedgerLegacySafety.test.ts +15 -4
- package/__tests__/evmSignTransaction.test.ts +1 -1
- package/__tests__/evmSignTypedData.test.ts +1 -1
- package/__tests__/logBlockEvent.test.ts +37 -0
- package/__tests__/protocol-v2.test.ts +3025 -0
- package/dist/api/BaseMethod.d.ts +1 -0
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/DirList.d.ts +10 -0
- package/dist/api/DirList.d.ts.map +1 -0
- package/dist/api/DirMake.d.ts +9 -0
- package/dist/api/DirMake.d.ts.map +1 -0
- package/dist/api/DirRemove.d.ts +9 -0
- package/dist/api/DirRemove.d.ts.map +1 -0
- package/dist/api/FileDelete.d.ts +9 -0
- package/dist/api/FileDelete.d.ts.map +1 -0
- package/dist/api/FileRead.d.ts +19 -0
- package/dist/api/FileRead.d.ts.map +1 -0
- package/dist/api/FileWrite.d.ts +24 -0
- package/dist/api/FileWrite.d.ts.map +1 -0
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +1 -0
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +35 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -0
- package/dist/api/GetDeviceInfo.d.ts +9 -0
- package/dist/api/GetDeviceInfo.d.ts.map +1 -0
- package/dist/api/GetFeatures.d.ts.map +1 -1
- package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts +6 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/PathInfo.d.ts +10 -0
- package/dist/api/PathInfo.d.ts.map +1 -0
- package/dist/api/PromptWebDeviceAccess.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts +2 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumGetAddress.d.ts +2 -6
- package/dist/api/alephium/AlephiumGetAddress.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumSignMessage.d.ts +2 -5
- package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumSignTransaction.d.ts +5 -8
- package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
- package/dist/api/aptos/AptosGetAddress.d.ts.map +1 -1
- package/dist/api/benfen/BenfenGetAddress.d.ts +2 -9
- package/dist/api/benfen/BenfenGetAddress.d.ts.map +1 -1
- package/dist/api/benfen/BenfenGetPublicKey.d.ts +2 -9
- package/dist/api/benfen/BenfenGetPublicKey.d.ts.map +1 -1
- package/dist/api/benfen/BenfenSignMessage.d.ts +2 -8
- package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
- package/dist/api/benfen/BenfenSignTransaction.d.ts +2 -8
- package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
- package/dist/api/btc/BTCGetAddress.d.ts +1 -11
- package/dist/api/btc/BTCGetAddress.d.ts.map +1 -1
- package/dist/api/btc/BTCGetPublicKey.d.ts +1 -11
- package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
- package/dist/api/btc/BTCSignMessage.d.ts +1 -15
- package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
- package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
- package/dist/api/btc/BTCSignTransaction.d.ts +1 -11
- package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
- package/dist/api/btc/BTCVerifyMessage.d.ts +1 -11
- package/dist/api/btc/BTCVerifyMessage.d.ts.map +1 -1
- package/dist/api/btc/helpers/versionLimit.d.ts +2 -11
- package/dist/api/btc/helpers/versionLimit.d.ts.map +1 -1
- package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
- package/dist/api/device/DeviceLock.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBoardloader.d.ts +1 -1
- package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceSupportFeatures.d.ts.map +1 -1
- package/dist/api/device/DeviceUploadResource.d.ts.map +1 -1
- package/dist/api/device/DeviceVerify.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/EVMGetPublicKey.d.ts.map +1 -1
- package/dist/api/evm/EVMSignMessageEIP712.d.ts +2 -8
- package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/evm/latest/signTypedData.d.ts +1 -1
- package/dist/api/evm/latest/signTypedData.d.ts.map +1 -1
- package/dist/api/evm/latest/signTypedHash.d.ts.map +1 -1
- package/dist/api/evm/legacyV1/getAddress.d.ts.map +1 -1
- package/dist/api/evm/legacyV1/getPublicKey.d.ts.map +1 -1
- package/dist/api/evm/legacyV1/signMessage.d.ts.map +1 -1
- package/dist/api/evm/legacyV1/signTypedData.d.ts +1 -1
- package/dist/api/evm/legacyV1/signTypedData.d.ts.map +1 -1
- package/dist/api/evm/legacyV1/signTypedHash.d.ts.map +1 -1
- package/dist/api/evm/legacyV1/verifyMessage.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/batchGetPublickeys.d.ts +3 -0
- package/dist/api/helpers/batchGetPublickeys.d.ts.map +1 -1
- package/dist/api/helpers/filesystemValidation.d.ts +7 -0
- package/dist/api/helpers/filesystemValidation.d.ts.map +1 -0
- package/dist/api/index.d.ts +32 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
- package/dist/api/lightning/LnurlAuth.d.ts +4 -0
- package/dist/api/lightning/LnurlAuth.d.ts.map +1 -1
- package/dist/api/neo/NeoGetAddress.d.ts +2 -8
- package/dist/api/neo/NeoGetAddress.d.ts.map +1 -1
- package/dist/api/neo/NeoSignTransaction.d.ts +2 -8
- package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
- package/dist/api/nervos/NervosGetAddress.d.ts +2 -9
- package/dist/api/nervos/NervosGetAddress.d.ts.map +1 -1
- package/dist/api/nervos/NervosSignTransaction.d.ts +9 -12
- package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
- package/dist/api/nexa/NexaGetAddress.d.ts +2 -8
- package/dist/api/nexa/NexaGetAddress.d.ts.map +1 -1
- package/dist/api/nexa/NexaSignTransaction.d.ts +2 -9
- package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotGetAddress.d.ts +3 -0
- package/dist/api/polkadot/PolkadotGetAddress.d.ts.map +1 -1
- package/dist/api/polkadot/networks.d.ts +3 -0
- package/dist/api/polkadot/networks.d.ts.map +1 -1
- package/dist/api/protocol-v2/DevReboot.d.ts +7 -0
- package/dist/api/protocol-v2/DevReboot.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts +29 -0
- package/dist/api/protocol-v2/DeviceGetDeviceInfo.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +6 -0
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceReboot.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -0
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts +7 -0
- package/dist/api/protocol-v2/FactoryDeviceInfoSettings.d.ts.map +1 -0
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts +6 -0
- package/dist/api/protocol-v2/FactoryGetDeviceInfo.d.ts.map +1 -0
- package/dist/api/protocol-v2/FilesystemDiskControl.d.ts +13 -0
- package/dist/api/protocol-v2/FilesystemDiskControl.d.ts.map +1 -0
- package/dist/api/protocol-v2/FilesystemFixPermission.d.ts +6 -0
- package/dist/api/protocol-v2/FilesystemFixPermission.d.ts.map +1 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts +6 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -0
- package/dist/api/protocol-v2/GetProtoVersion.d.ts +6 -0
- package/dist/api/protocol-v2/GetProtoVersion.d.ts.map +1 -0
- package/dist/api/protocol-v2/Ping.d.ts +8 -0
- package/dist/api/protocol-v2/Ping.d.ts.map +1 -0
- package/dist/api/protocol-v2/helpers.d.ts +34 -0
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -0
- package/dist/api/scdo/ScdoGetAddress.d.ts +2 -6
- package/dist/api/scdo/ScdoGetAddress.d.ts.map +1 -1
- package/dist/api/scdo/ScdoSignMessage.d.ts +2 -5
- package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
- package/dist/api/scdo/ScdoSignTransaction.d.ts +2 -5
- 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 +3 -0
- package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts +3 -0
- package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
- package/dist/api/solana/SolSignTransaction.d.ts +6 -0
- package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
- package/dist/api/stellar/StellarGetAddress.d.ts +2 -1
- package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +3 -2
- package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
- package/dist/api/sui/SuiGetAddress.d.ts +3 -0
- package/dist/api/sui/SuiGetAddress.d.ts.map +1 -1
- package/dist/api/sui/SuiGetPublicKey.d.ts +3 -0
- package/dist/api/sui/SuiGetPublicKey.d.ts.map +1 -1
- package/dist/api/sui/SuiSignMessage.d.ts +3 -0
- package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
- package/dist/api/sui/SuiSignTransaction.d.ts +5 -2
- package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
- package/dist/api/ton/TonGetAddress.d.ts +3 -0
- package/dist/api/ton/TonGetAddress.d.ts.map +1 -1
- package/dist/api/ton/TonSignData.d.ts +5 -0
- package/dist/api/ton/TonSignData.d.ts.map +1 -1
- package/dist/api/ton/TonSignMessage.d.ts +3 -0
- package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
- package/dist/api/ton/TonSignProof.d.ts +3 -0
- package/dist/api/ton/TonSignProof.d.ts.map +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +4 -0
- package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
- package/dist/api/tron/TronSignTransaction.d.ts +4 -0
- package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/DataManager.d.ts +7 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/MessagesConfig.d.ts +2 -2
- package/dist/data-manager/MessagesConfig.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.d.ts +5 -4
- package/dist/data-manager/TransportManager.d.ts.map +1 -1
- package/dist/device/Device.d.ts +36 -10
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +9 -9
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceConnector.d.ts +2 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/deviceProfile/buildDeviceProfile.d.ts +22 -0
- package/dist/deviceProfile/buildDeviceProfile.d.ts.map +1 -0
- package/dist/deviceProfile/index.d.ts +3 -0
- package/dist/deviceProfile/index.d.ts.map +1 -0
- package/dist/deviceProfile/legacyFeaturesView.d.ts +5 -0
- package/dist/deviceProfile/legacyFeaturesView.d.ts.map +1 -0
- package/dist/events/logBlockEvent.d.ts +1 -0
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +8 -0
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +720 -382
- package/dist/index.js +17634 -1201
- package/dist/inject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts +93 -0
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/firmware.d.ts +13 -0
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/index.d.ts +4 -0
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -0
- package/dist/types/api/export.d.ts +1 -1
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +27 -0
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/getDeviceInfo.d.ts +85 -0
- package/dist/types/api/getDeviceInfo.d.ts.map +1 -0
- package/dist/types/api/getPassphraseState.d.ts +10 -1
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +37 -1
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +103 -0
- package/dist/types/api/protocolV2.d.ts.map +1 -0
- package/dist/types/api/searchDevices.d.ts +2 -2
- package/dist/types/api/searchDevices.d.ts.map +1 -1
- package/dist/types/device.d.ts +10 -3
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +2 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +1 -1
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +6 -8
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts +1 -0
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +26 -22
- package/src/api/DirList.ts +31 -0
- package/src/api/DirMake.ts +23 -0
- package/src/api/DirRemove.ts +23 -0
- package/src/api/FileDelete.ts +23 -0
- package/src/api/FileRead.ts +167 -0
- package/src/api/FileWrite.ts +216 -0
- package/src/api/FirmwareUpdate.ts +13 -5
- package/src/api/FirmwareUpdateV2.ts +21 -25
- package/src/api/FirmwareUpdateV3.ts +17 -4
- package/src/api/FirmwareUpdateV4.ts +827 -0
- package/src/api/GetDeviceInfo.ts +152 -0
- package/src/api/GetFeatures.ts +5 -2
- package/src/api/GetOnekeyFeatures.ts +95 -3
- package/src/api/GetPassphraseState.ts +16 -10
- package/src/api/PathInfo.ts +39 -0
- package/src/api/PromptWebDeviceAccess.ts +11 -1
- package/src/api/SearchDevices.ts +7 -2
- package/src/api/alephium/AlephiumGetAddress.ts +6 -2
- package/src/api/alephium/AlephiumSignMessage.ts +6 -1
- package/src/api/alephium/AlephiumSignTransaction.ts +15 -4
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +21 -13
- package/src/api/aptos/AptosGetAddress.ts +2 -3
- package/src/api/benfen/BenfenGetAddress.ts +11 -7
- package/src/api/benfen/BenfenGetPublicKey.ts +6 -2
- package/src/api/benfen/BenfenSignMessage.ts +6 -1
- package/src/api/benfen/BenfenSignTransaction.ts +6 -1
- package/src/api/btc/BTCGetPublicKey.ts +3 -2
- package/src/api/btc/BTCSignPsbt.ts +1 -2
- package/src/api/btc/helpers/versionLimit.ts +7 -1
- package/src/api/cardano/CardanoSignTransaction.ts +2 -4
- package/src/api/conflux/ConfluxSignTransaction.ts +5 -2
- package/src/api/device/DeviceFullyUploadResource.ts +3 -3
- package/src/api/device/DeviceLock.ts +1 -3
- package/src/api/device/DeviceRebootToBoardloader.ts +10 -1
- package/src/api/device/DeviceRebootToBootloader.ts +10 -1
- package/src/api/device/DeviceSupportFeatures.ts +2 -13
- package/src/api/device/DeviceUpdateBootloader.ts +4 -4
- package/src/api/device/DeviceUploadResource.ts +4 -5
- package/src/api/device/DeviceVerify.ts +1 -2
- package/src/api/dynex/DnxGetAddress.ts +6 -0
- package/src/api/dynex/DnxSignTransaction.ts +6 -0
- package/src/api/evm/EVMGetAddress.ts +1 -1
- package/src/api/evm/EVMGetPublicKey.ts +3 -4
- package/src/api/evm/EVMSignMessage.ts +1 -1
- package/src/api/evm/EVMSignMessageEIP712.ts +14 -1
- package/src/api/evm/EVMSignTransaction.ts +1 -1
- package/src/api/evm/EVMSignTypedData.ts +32 -18
- package/src/api/evm/EVMVerifyMessage.ts +1 -1
- package/src/api/evm/latest/signTypedHash.ts +2 -4
- package/src/api/evm/legacyV1/getAddress.ts +5 -3
- package/src/api/evm/legacyV1/getPublicKey.ts +5 -3
- package/src/api/evm/legacyV1/signMessage.ts +5 -3
- package/src/api/evm/legacyV1/signTypedData.ts +9 -8
- package/src/api/evm/legacyV1/signTypedHash.ts +7 -7
- package/src/api/evm/legacyV1/verifyMessage.ts +5 -3
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +8 -8
- package/src/api/firmware/uploadFirmware.ts +3 -10
- package/src/api/helpers/batchGetPublickeys.ts +51 -6
- package/src/api/helpers/filesystemValidation.ts +51 -0
- package/src/api/index.ts +34 -0
- package/src/api/kaspa/KaspaSignTransaction.ts +4 -5
- package/src/api/lightning/LnurlAuth.ts +4 -0
- package/src/api/neo/NeoGetAddress.ts +6 -1
- package/src/api/neo/NeoSignTransaction.ts +6 -1
- package/src/api/nervos/NervosGetAddress.ts +6 -2
- package/src/api/nervos/NervosSignTransaction.ts +14 -4
- package/src/api/nexa/NexaGetAddress.ts +6 -2
- package/src/api/nexa/NexaSignTransaction.ts +11 -12
- package/src/api/polkadot/networks.ts +9 -0
- package/src/api/protocol-v2/DevReboot.ts +24 -0
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +63 -0
- package/src/api/protocol-v2/DeviceGetDeviceInfo.ts +118 -0
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +20 -0
- package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +16 -0
- package/src/api/protocol-v2/DeviceReboot.ts +24 -0
- package/src/api/protocol-v2/FactoryDeviceInfoSettings.ts +29 -0
- package/src/api/protocol-v2/FactoryGetDeviceInfo.ts +20 -0
- package/src/api/protocol-v2/FilesystemDiskControl.ts +50 -0
- package/src/api/protocol-v2/FilesystemFixPermission.ts +16 -0
- package/src/api/protocol-v2/FilesystemFormat.ts +16 -0
- package/src/api/protocol-v2/GetProtoVersion.ts +16 -0
- package/src/api/protocol-v2/Ping.ts +18 -0
- package/src/api/protocol-v2/helpers.ts +207 -0
- package/src/api/scdo/ScdoGetAddress.ts +6 -2
- package/src/api/scdo/ScdoSignMessage.ts +6 -1
- package/src/api/scdo/ScdoSignTransaction.ts +6 -2
- package/src/api/solana/SolGetAddress.ts +4 -0
- package/src/api/solana/SolSignMessage.ts +3 -0
- package/src/api/solana/SolSignOffchainMessage.ts +3 -0
- package/src/api/solana/SolSignTransaction.ts +6 -0
- package/src/api/stellar/StellarGetAddress.ts +10 -1
- package/src/api/stellar/StellarSignTransaction.ts +14 -1
- package/src/api/sui/SuiGetAddress.ts +5 -3
- package/src/api/sui/SuiGetPublicKey.ts +3 -0
- package/src/api/sui/SuiSignMessage.ts +3 -0
- package/src/api/sui/SuiSignTransaction.ts +14 -12
- package/src/api/ton/TonGetAddress.ts +3 -0
- package/src/api/ton/TonSignData.ts +10 -3
- package/src/api/ton/TonSignMessage.ts +6 -5
- package/src/api/ton/TonSignProof.ts +3 -0
- package/src/api/tron/TronSignMessage.ts +5 -1
- package/src/api/tron/TronSignTransaction.ts +4 -0
- package/src/api/xrp/XrpSignTransaction.ts +1 -1
- package/src/core/index.ts +87 -55
- package/src/data/messages/messages-protocol-v2.json +13369 -0
- package/src/data-manager/DataManager.ts +12 -7
- package/src/data-manager/MessagesConfig.ts +14 -14
- package/src/data-manager/TransportManager.ts +38 -12
- package/src/device/Device.ts +538 -61
- package/src/device/DeviceCommands.ts +195 -29
- package/src/device/DeviceConnector.ts +29 -4
- package/src/device/DevicePool.ts +7 -7
- package/src/deviceProfile/buildDeviceProfile.ts +387 -0
- package/src/deviceProfile/index.ts +2 -0
- package/src/deviceProfile/legacyFeaturesView.ts +123 -0
- package/src/events/logBlockEvent.ts +23 -0
- package/src/events/ui-request.ts +8 -0
- package/src/inject.ts +52 -1
- package/src/protocols/protocol-v2/features.ts +180 -0
- package/src/protocols/protocol-v2/firmware.ts +43 -0
- package/src/protocols/protocol-v2/index.ts +16 -0
- package/src/types/api/export.ts +1 -0
- package/src/types/api/firmwareUpdate.ts +49 -0
- package/src/types/api/getDeviceInfo.ts +99 -0
- package/src/types/api/getPassphraseState.ts +13 -2
- package/src/types/api/index.ts +88 -1
- package/src/types/api/protocolV2.ts +201 -0
- package/src/types/api/searchDevices.ts +2 -2
- package/src/types/device.ts +37 -3
- package/src/types/params.ts +7 -0
- package/src/types/settings.ts +1 -1
- package/src/utils/deviceFeaturesUtils.ts +70 -70
- package/src/utils/deviceInfoUtils.ts +15 -8
- package/src/utils/index.ts +1 -0
package/src/api/BaseMethod.ts
CHANGED
|
@@ -4,20 +4,12 @@ import {
|
|
|
4
4
|
createNeedUpgradeFirmwareHardwareError,
|
|
5
5
|
} from '@onekeyfe/hd-shared';
|
|
6
6
|
|
|
7
|
-
import { supportInputPinOnSoftware, supportModifyHomescreen } from '../utils/deviceFeaturesUtils';
|
|
8
7
|
import { createDeviceMessage } from '../events/device';
|
|
9
8
|
import { UI_REQUEST } from '../constants/ui-request';
|
|
10
9
|
import { DEVICE, FIRMWARE, createFirmwareMessage, createUiMessage } from '../events';
|
|
11
10
|
import { getHDPath, toHardened } from './helpers/pathUtils';
|
|
12
11
|
import { getBleFirmwareReleaseInfo, getFirmwareReleaseInfo } from './firmware/releaseHelper';
|
|
13
|
-
import {
|
|
14
|
-
LoggerNames,
|
|
15
|
-
getDeviceFirmwareVersion,
|
|
16
|
-
getDeviceType,
|
|
17
|
-
getFirmwareType,
|
|
18
|
-
getLogger,
|
|
19
|
-
getMethodVersionRange,
|
|
20
|
-
} from '../utils';
|
|
12
|
+
import { LoggerNames, getFirmwareType, getLogger, isMethodVersionRangeUnsupported } from '../utils';
|
|
21
13
|
import { generateInstanceId } from '../utils/tracing';
|
|
22
14
|
import { DeviceModelToTypes } from '../types';
|
|
23
15
|
|
|
@@ -162,6 +154,14 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
162
154
|
*/
|
|
163
155
|
strictCheckDeviceSupport = false;
|
|
164
156
|
|
|
157
|
+
/**
|
|
158
|
+
* 方法是否仅支持 Protocol V2 设备(Pro2)。
|
|
159
|
+
* core 调度在设备协议确定(acquire + initialize)后统一守卫,
|
|
160
|
+
* 非 V2 设备直接抛出 NotSupport 错误,方法内部不必重复判断。
|
|
161
|
+
* @default false
|
|
162
|
+
*/
|
|
163
|
+
requireProtocolV2 = false;
|
|
164
|
+
|
|
165
165
|
// @ts-expect-error: strictPropertyInitialization
|
|
166
166
|
postMessage: (message: CoreMessage) => void;
|
|
167
167
|
|
|
@@ -225,7 +225,10 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
checkFirmwareRelease() {
|
|
228
|
-
|
|
228
|
+
// 固件 release 元数据(DataManager remote config)目前只覆盖 Protocol V1 设备;
|
|
229
|
+
// Pro2 的更新流程由 firmwareUpdateV4 自行管理,这里显式跳过而不是依赖 features 为空。
|
|
230
|
+
if (!this.device || this.device.isProtocolV2()) return;
|
|
231
|
+
if (!this.device.features) return;
|
|
229
232
|
const firmwareType = getFirmwareType(this.device.features);
|
|
230
233
|
const releaseInfo = getFirmwareReleaseInfo(this.device.features, firmwareType);
|
|
231
234
|
this.postMessage(
|
|
@@ -244,9 +247,9 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
checkDeviceSupportFeature() {
|
|
247
|
-
if (!this.device ||
|
|
248
|
-
const inputPinOnSoftware =
|
|
249
|
-
const modifyHomescreen =
|
|
250
|
+
if (!this.device || this.device.isUnacquired()) return;
|
|
251
|
+
const inputPinOnSoftware = this.device.supportInputPinOnSoftware();
|
|
252
|
+
const modifyHomescreen = this.device.supportModifyHomescreen();
|
|
250
253
|
|
|
251
254
|
this.postMessage(
|
|
252
255
|
createDeviceMessage(DEVICE.SUPPORT_FEATURES, {
|
|
@@ -268,15 +271,16 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
268
271
|
return;
|
|
269
272
|
}
|
|
270
273
|
|
|
271
|
-
const firmwareVersion =
|
|
272
|
-
const versionRange =
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
274
|
+
const firmwareVersion = this.device.getCurrentFirmwareVersionString() ?? '0.0.0';
|
|
275
|
+
const versionRange = this.device.getCurrentMethodVersionRange(type => getVersionRange()[type]);
|
|
276
|
+
|
|
277
|
+
if (isMethodVersionRangeUnsupported(versionRange)) {
|
|
278
|
+
throw createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
279
|
+
}
|
|
276
280
|
|
|
277
281
|
if (!versionRange) {
|
|
278
282
|
if (options?.strictCheckDeviceSupport) {
|
|
279
|
-
throw createDeviceNotSupportMethodError(this.name,
|
|
283
|
+
throw createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
280
284
|
}
|
|
281
285
|
// Equipment that does not need to be repaired
|
|
282
286
|
return;
|
|
@@ -287,7 +291,7 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
287
291
|
currentVersion: firmwareVersion,
|
|
288
292
|
requireVersion: versionRange.min,
|
|
289
293
|
methodName: this.name,
|
|
290
|
-
firmwareType:
|
|
294
|
+
firmwareType: this.device.getCurrentFirmwareType(),
|
|
291
295
|
});
|
|
292
296
|
}
|
|
293
297
|
}
|
|
@@ -297,7 +301,7 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
297
301
|
return false;
|
|
298
302
|
}
|
|
299
303
|
|
|
300
|
-
const deviceType =
|
|
304
|
+
const deviceType = this.device.getCurrentDeviceType();
|
|
301
305
|
if (!DeviceModelToTypes.model_touch.includes(deviceType)) {
|
|
302
306
|
return false;
|
|
303
307
|
}
|
|
@@ -329,7 +333,7 @@ export abstract class BaseMethod<Params = undefined> {
|
|
|
329
333
|
if (this.shouldPromptSafetyCheckForEvmLedgerLegacyPath()) {
|
|
330
334
|
checkFlag = true;
|
|
331
335
|
}
|
|
332
|
-
if (checkFlag && this.device.
|
|
336
|
+
if (checkFlag && this.device.getCurrentSafetyChecks() === 'Strict') {
|
|
333
337
|
Log.debug('will change safety_checks level');
|
|
334
338
|
await this.device.commands.typedCall('ApplySettings', 'Success', {
|
|
335
339
|
safety_checks: 'PromptTemporarily',
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import {
|
|
3
|
+
validateNonEmptyString,
|
|
4
|
+
validateOptionalNonNegativeInteger,
|
|
5
|
+
} from './helpers/filesystemValidation';
|
|
6
|
+
|
|
7
|
+
export type DirListParams = {
|
|
8
|
+
path: string;
|
|
9
|
+
depth?: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default class DirList extends BaseMethod<DirListParams> {
|
|
13
|
+
init() {
|
|
14
|
+
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
15
|
+
this.requireProtocolV2 = true;
|
|
16
|
+
this.skipForceUpdateCheck = true;
|
|
17
|
+
this.useDevicePassphraseState = false;
|
|
18
|
+
this.params = {
|
|
19
|
+
path: validateNonEmptyString(this.payload.path, 'path'),
|
|
20
|
+
depth: validateOptionalNonNegativeInteger(this.payload.depth, 'depth'),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async run() {
|
|
25
|
+
const res = await this.device.commands.typedCall('FilesystemDirList', 'FilesystemDir', {
|
|
26
|
+
path: this.params.path,
|
|
27
|
+
depth: this.params.depth,
|
|
28
|
+
});
|
|
29
|
+
return Promise.resolve(res.message);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import { validateNonEmptyString } from './helpers/filesystemValidation';
|
|
3
|
+
|
|
4
|
+
export type DirMakeParams = {
|
|
5
|
+
path: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default class DirMake extends BaseMethod<DirMakeParams> {
|
|
9
|
+
init() {
|
|
10
|
+
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
11
|
+
this.requireProtocolV2 = true;
|
|
12
|
+
this.skipForceUpdateCheck = true;
|
|
13
|
+
this.useDevicePassphraseState = false;
|
|
14
|
+
this.params = { path: validateNonEmptyString(this.payload.path, 'path') };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async run() {
|
|
18
|
+
const res = await this.device.commands.typedCall('FilesystemDirMake', 'Success', {
|
|
19
|
+
path: this.params.path,
|
|
20
|
+
});
|
|
21
|
+
return Promise.resolve(res.message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import { validateNonEmptyString } from './helpers/filesystemValidation';
|
|
3
|
+
|
|
4
|
+
export type DirRemoveParams = {
|
|
5
|
+
path: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default class DirRemove extends BaseMethod<DirRemoveParams> {
|
|
9
|
+
init() {
|
|
10
|
+
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
11
|
+
this.requireProtocolV2 = true;
|
|
12
|
+
this.skipForceUpdateCheck = true;
|
|
13
|
+
this.useDevicePassphraseState = false;
|
|
14
|
+
this.params = { path: validateNonEmptyString(this.payload.path, 'path') };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async run() {
|
|
18
|
+
const res = await this.device.commands.typedCall('FilesystemDirRemove', 'Success', {
|
|
19
|
+
path: this.params.path,
|
|
20
|
+
});
|
|
21
|
+
return Promise.resolve(res.message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import { validateNonEmptyString } from './helpers/filesystemValidation';
|
|
3
|
+
|
|
4
|
+
export type FileDeleteParams = {
|
|
5
|
+
path: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export default class FileDelete extends BaseMethod<FileDeleteParams> {
|
|
9
|
+
init() {
|
|
10
|
+
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
11
|
+
this.requireProtocolV2 = true;
|
|
12
|
+
this.skipForceUpdateCheck = true;
|
|
13
|
+
this.useDevicePassphraseState = false;
|
|
14
|
+
this.params = { path: validateNonEmptyString(this.payload.path, 'path') };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async run() {
|
|
18
|
+
const res = await this.device.commands.typedCall('FilesystemFileDelete', 'Success', {
|
|
19
|
+
path: this.params.path,
|
|
20
|
+
});
|
|
21
|
+
return Promise.resolve(res.message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
|
|
3
|
+
PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
|
|
4
|
+
} from '@onekeyfe/hd-transport';
|
|
5
|
+
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
6
|
+
|
|
7
|
+
import { BaseMethod } from './BaseMethod';
|
|
8
|
+
import {
|
|
9
|
+
validateNonEmptyString,
|
|
10
|
+
validateNonNegativeInteger,
|
|
11
|
+
validateOptionalNonNegativeInteger,
|
|
12
|
+
validateOptionalPercentage,
|
|
13
|
+
} from './helpers/filesystemValidation';
|
|
14
|
+
import { hexToBytes, isHexString, stripHexPrefix } from './helpers/hexUtils';
|
|
15
|
+
import { DataManager } from '../data-manager';
|
|
16
|
+
|
|
17
|
+
export type FileReadParams = {
|
|
18
|
+
path: string;
|
|
19
|
+
offset?: number;
|
|
20
|
+
totalSize?: number;
|
|
21
|
+
chunkLen?: number;
|
|
22
|
+
uiPercentage?: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const MIN_FILE_READ_CHUNK_SIZE = 64;
|
|
26
|
+
|
|
27
|
+
function getProtocolV2FileReadChunkLimit() {
|
|
28
|
+
const env = DataManager.getSettings('env');
|
|
29
|
+
if (env && DataManager.isBleConnect(env)) {
|
|
30
|
+
return PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
|
|
31
|
+
}
|
|
32
|
+
return PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeChunkSize(value: unknown, maxChunkSize: number): number {
|
|
36
|
+
const numeric = Number(value);
|
|
37
|
+
if (!Number.isFinite(numeric) || numeric <= 0) return maxChunkSize;
|
|
38
|
+
return Math.min(Math.max(Math.floor(numeric), MIN_FILE_READ_CHUNK_SIZE), maxChunkSize);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function toFiniteNumber(value: unknown): number | undefined {
|
|
42
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
43
|
+
if (typeof value === 'string') {
|
|
44
|
+
const numeric = Number(value);
|
|
45
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
46
|
+
}
|
|
47
|
+
if (value && typeof value === 'object') {
|
|
48
|
+
const longLike = value as { toNumber?: () => number };
|
|
49
|
+
if (typeof longLike.toNumber === 'function') {
|
|
50
|
+
const numeric = longLike.toNumber();
|
|
51
|
+
return Number.isFinite(numeric) ? numeric : undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function toUint8Array(value: unknown): Uint8Array {
|
|
58
|
+
if (value instanceof Uint8Array) return value;
|
|
59
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
60
|
+
if (ArrayBuffer.isView(value)) {
|
|
61
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
62
|
+
}
|
|
63
|
+
if (typeof value === 'string') {
|
|
64
|
+
const hex = stripHexPrefix(value);
|
|
65
|
+
if (!hex) return new Uint8Array(0);
|
|
66
|
+
if (!isHexString(hex) || hex.length % 2 !== 0) return new Uint8Array(0);
|
|
67
|
+
return hexToBytes(hex);
|
|
68
|
+
}
|
|
69
|
+
return new Uint8Array(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default class FileRead extends BaseMethod<FileReadParams> {
|
|
73
|
+
init() {
|
|
74
|
+
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
75
|
+
this.requireProtocolV2 = true;
|
|
76
|
+
this.skipForceUpdateCheck = true;
|
|
77
|
+
this.useDevicePassphraseState = false;
|
|
78
|
+
const path = validateNonEmptyString(this.payload.path, 'path');
|
|
79
|
+
this.params = {
|
|
80
|
+
path,
|
|
81
|
+
offset: validateNonNegativeInteger(this.payload.offset, 'offset', 0),
|
|
82
|
+
totalSize: validateNonNegativeInteger(this.payload.totalSize, 'totalSize', 0),
|
|
83
|
+
chunkLen: validateOptionalNonNegativeInteger(this.payload.chunkLen, 'chunkLen'),
|
|
84
|
+
uiPercentage: validateOptionalPercentage(this.payload.uiPercentage, 'uiPercentage'),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async run() {
|
|
89
|
+
const startOffset = this.params.offset ?? 0;
|
|
90
|
+
const requestedLength = Number(this.params.totalSize);
|
|
91
|
+
const chunkSize = normalizeChunkSize(this.params.chunkLen, getProtocolV2FileReadChunkLimit());
|
|
92
|
+
let totalLength = Number.isFinite(requestedLength) && requestedLength > 0 ? requestedLength : 0;
|
|
93
|
+
|
|
94
|
+
if (totalLength === 0) {
|
|
95
|
+
const pathInfoRes = await this.device.commands.typedCall(
|
|
96
|
+
'FilesystemPathInfoQuery',
|
|
97
|
+
'FilesystemPathInfo',
|
|
98
|
+
{
|
|
99
|
+
path: this.params.path,
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
const fileSize = toFiniteNumber(pathInfoRes.message?.size);
|
|
103
|
+
if (!pathInfoRes.message?.exist || pathInfoRes.message?.directory) {
|
|
104
|
+
throw ERRORS.TypedError(
|
|
105
|
+
HardwareErrorCode.RuntimeError,
|
|
106
|
+
`FilesystemFileRead path is not a file: ${this.params.path}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
if (fileSize === undefined || fileSize < startOffset) {
|
|
110
|
+
throw ERRORS.TypedError(
|
|
111
|
+
HardwareErrorCode.RuntimeError,
|
|
112
|
+
`FilesystemFileRead invalid offset ${startOffset} for ${this.params.path}`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
totalLength = fileSize - startOffset;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const chunks: Uint8Array[] = [];
|
|
119
|
+
let read = 0;
|
|
120
|
+
let lastMessage: Record<string, unknown> | undefined;
|
|
121
|
+
|
|
122
|
+
while (read < totalLength) {
|
|
123
|
+
const readLen = Math.min(chunkSize, totalLength - read);
|
|
124
|
+
const offset = startOffset + read;
|
|
125
|
+
const progress =
|
|
126
|
+
this.params.uiPercentage ??
|
|
127
|
+
Math.min(Math.ceil(((read + readLen) / Math.max(totalLength, 1)) * 100), 99);
|
|
128
|
+
const res = await this.device.commands.typedCall('FilesystemFileRead', 'FilesystemFile', {
|
|
129
|
+
file: {
|
|
130
|
+
path: this.params.path,
|
|
131
|
+
offset,
|
|
132
|
+
total_size: 0,
|
|
133
|
+
},
|
|
134
|
+
chunk_len: readLen,
|
|
135
|
+
ui_percentage: progress,
|
|
136
|
+
});
|
|
137
|
+
const data = toUint8Array(res.message?.data);
|
|
138
|
+
lastMessage = res.message;
|
|
139
|
+
|
|
140
|
+
if (data.byteLength === 0) {
|
|
141
|
+
throw ERRORS.TypedError(
|
|
142
|
+
HardwareErrorCode.RuntimeError,
|
|
143
|
+
`FilesystemFileRead received empty data at offset ${offset}`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
chunks.push(data);
|
|
148
|
+
read += data.byteLength;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const combined = new Uint8Array(read);
|
|
152
|
+
let cursor = 0;
|
|
153
|
+
chunks.forEach(chunk => {
|
|
154
|
+
combined.set(chunk, cursor);
|
|
155
|
+
cursor += chunk.byteLength;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return Promise.resolve({
|
|
159
|
+
...lastMessage,
|
|
160
|
+
path: this.params.path,
|
|
161
|
+
offset: startOffset,
|
|
162
|
+
total_size: totalLength,
|
|
163
|
+
data: combined,
|
|
164
|
+
chunks: chunks.length,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
|
|
3
|
+
PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
|
|
4
|
+
} from '@onekeyfe/hd-transport';
|
|
5
|
+
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
6
|
+
|
|
7
|
+
import { BaseMethod } from './BaseMethod';
|
|
8
|
+
import {
|
|
9
|
+
validateNonEmptyString,
|
|
10
|
+
validateNonNegativeInteger,
|
|
11
|
+
validateOptionalNonNegativeInteger,
|
|
12
|
+
validateOptionalPercentage,
|
|
13
|
+
validateRequiredData,
|
|
14
|
+
} from './helpers/filesystemValidation';
|
|
15
|
+
import { UI_REQUEST, createUiMessage } from '../events/ui-request';
|
|
16
|
+
import { DataManager } from '../data-manager';
|
|
17
|
+
|
|
18
|
+
export type FileWriteParams = {
|
|
19
|
+
path: string;
|
|
20
|
+
offset?: number;
|
|
21
|
+
totalSize?: number;
|
|
22
|
+
data: ArrayBuffer | Uint8Array | Blob | string;
|
|
23
|
+
chunkSize?: number;
|
|
24
|
+
chunkLen?: number;
|
|
25
|
+
overwrite?: boolean;
|
|
26
|
+
append?: boolean;
|
|
27
|
+
uiPercentage?: number;
|
|
28
|
+
timeoutMs?: number | string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const MIN_FILE_CHUNK_SIZE = 64;
|
|
32
|
+
|
|
33
|
+
function getProtocolV2FileChunkLimit() {
|
|
34
|
+
const env = DataManager.getSettings('env');
|
|
35
|
+
if (env && DataManager.isBleConnect(env)) {
|
|
36
|
+
return PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
|
|
37
|
+
}
|
|
38
|
+
return PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function dataToUint8Array(data: FileWriteParams['data'] | Blob): Promise<Uint8Array> {
|
|
42
|
+
if (typeof data === 'string') {
|
|
43
|
+
return new TextEncoder().encode(data);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (data instanceof ArrayBuffer) {
|
|
47
|
+
return new Uint8Array(data);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (ArrayBuffer.isView(data)) {
|
|
51
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob) {
|
|
55
|
+
return new Uint8Array(await data.arrayBuffer());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
throw ERRORS.TypedError(
|
|
59
|
+
HardwareErrorCode.CallMethodInvalidParameter,
|
|
60
|
+
'Unsupported FilesystemFileWrite data'
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function normalizeChunkSize(value: unknown, maxChunkSize: number): number {
|
|
65
|
+
const numeric = Number(value);
|
|
66
|
+
if (!Number.isFinite(numeric) || numeric <= 0) return maxChunkSize;
|
|
67
|
+
return Math.min(Math.max(Math.floor(numeric), MIN_FILE_CHUNK_SIZE), maxChunkSize);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function getConfirmedProgress(
|
|
71
|
+
processedByte: number,
|
|
72
|
+
totalSize: number,
|
|
73
|
+
written: number,
|
|
74
|
+
dataLength: number
|
|
75
|
+
) {
|
|
76
|
+
if (Number.isFinite(processedByte) && Number.isFinite(totalSize) && totalSize > 0) {
|
|
77
|
+
if (processedByte >= totalSize) return 100;
|
|
78
|
+
return Math.min(Math.max(Math.floor((processedByte / totalSize) * 100), 0), 99);
|
|
79
|
+
}
|
|
80
|
+
if (dataLength > 0) {
|
|
81
|
+
if (written >= dataLength) return 100;
|
|
82
|
+
return Math.min(Math.max(Math.floor((written / dataLength) * 100), 0), 99);
|
|
83
|
+
}
|
|
84
|
+
return 100;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default class FileWrite extends BaseMethod<FileWriteParams> {
|
|
88
|
+
init() {
|
|
89
|
+
// Protocol V2 (Pro2) 专属方法,core 调度层统一做非 V2 设备守卫
|
|
90
|
+
this.requireProtocolV2 = true;
|
|
91
|
+
this.skipForceUpdateCheck = true;
|
|
92
|
+
this.useDevicePassphraseState = false;
|
|
93
|
+
validateRequiredData(this.payload.data, 'data');
|
|
94
|
+
const path = validateNonEmptyString(this.payload.path, 'path');
|
|
95
|
+
const offset = validateNonNegativeInteger(this.payload.offset, 'offset', 0);
|
|
96
|
+
this.params = {
|
|
97
|
+
path,
|
|
98
|
+
offset,
|
|
99
|
+
totalSize: validateNonNegativeInteger(this.payload.totalSize, 'totalSize', 0),
|
|
100
|
+
data: this.payload.data,
|
|
101
|
+
chunkSize: validateOptionalNonNegativeInteger(this.payload.chunkSize, 'chunkSize'),
|
|
102
|
+
chunkLen: validateOptionalNonNegativeInteger(this.payload.chunkLen, 'chunkLen'),
|
|
103
|
+
overwrite: this.payload.overwrite ?? offset === 0,
|
|
104
|
+
append: this.payload.append ?? false,
|
|
105
|
+
uiPercentage: validateOptionalPercentage(this.payload.uiPercentage, 'uiPercentage'),
|
|
106
|
+
timeoutMs: validateOptionalNonNegativeInteger(this.payload.timeoutMs, 'timeoutMs'),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async run() {
|
|
111
|
+
const data = await dataToUint8Array(this.params.data);
|
|
112
|
+
const dataLength = data.byteLength;
|
|
113
|
+
const offsetValue = Number(this.params.offset ?? 0);
|
|
114
|
+
const startOffset = Number.isFinite(offsetValue) && offsetValue > 0 ? offsetValue : 0;
|
|
115
|
+
const payloadTotalSize = Number(this.params.totalSize);
|
|
116
|
+
const totalSize =
|
|
117
|
+
Number.isFinite(payloadTotalSize) && payloadTotalSize > 0
|
|
118
|
+
? payloadTotalSize
|
|
119
|
+
: startOffset + dataLength;
|
|
120
|
+
|
|
121
|
+
if (totalSize < startOffset + dataLength) {
|
|
122
|
+
throw ERRORS.TypedError(
|
|
123
|
+
HardwareErrorCode.RuntimeError,
|
|
124
|
+
`FilesystemFileWrite totalSize ${totalSize} is smaller than offset + data length ${
|
|
125
|
+
startOffset + dataLength
|
|
126
|
+
}`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const chunkSize = normalizeChunkSize(
|
|
131
|
+
this.params.chunkSize ?? this.params.chunkLen,
|
|
132
|
+
getProtocolV2FileChunkLimit()
|
|
133
|
+
);
|
|
134
|
+
const overwrite = this.params.overwrite ?? false;
|
|
135
|
+
const append = this.params.append ?? false;
|
|
136
|
+
let written = 0;
|
|
137
|
+
let chunkIndex = 0;
|
|
138
|
+
let lastMessage: Record<string, unknown> | undefined;
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
const timeoutMs =
|
|
141
|
+
this.params.timeoutMs === undefined ? undefined : Number(this.params.timeoutMs);
|
|
142
|
+
|
|
143
|
+
while (written < dataLength) {
|
|
144
|
+
const chunkEnd = Math.min(written + chunkSize, dataLength);
|
|
145
|
+
const chunk = data.slice(written, chunkEnd);
|
|
146
|
+
const offset = startOffset + written;
|
|
147
|
+
const isFirstChunk = chunkIndex === 0;
|
|
148
|
+
const progress =
|
|
149
|
+
this.params.uiPercentage ??
|
|
150
|
+
Math.min(Math.ceil(((written + chunk.byteLength) / dataLength) * 100), 99);
|
|
151
|
+
|
|
152
|
+
const res = await this.device.commands.typedCall(
|
|
153
|
+
'FilesystemFileWrite',
|
|
154
|
+
'FilesystemFile',
|
|
155
|
+
{
|
|
156
|
+
file: {
|
|
157
|
+
path: this.params.path,
|
|
158
|
+
offset,
|
|
159
|
+
total_size: totalSize,
|
|
160
|
+
data: chunk,
|
|
161
|
+
},
|
|
162
|
+
overwrite: isFirstChunk ? overwrite : false,
|
|
163
|
+
append,
|
|
164
|
+
ui_percentage: progress,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
timeoutMs,
|
|
168
|
+
}
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
lastMessage = res.message;
|
|
172
|
+
const processedByte = Number(res.message?.processed_byte);
|
|
173
|
+
if (Number.isFinite(processedByte) && processedByte > offset) {
|
|
174
|
+
written = processedByte - startOffset;
|
|
175
|
+
} else {
|
|
176
|
+
written += chunk.byteLength;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (written > dataLength) {
|
|
180
|
+
throw ERRORS.TypedError(
|
|
181
|
+
HardwareErrorCode.RuntimeError,
|
|
182
|
+
`FilesystemFileWrite invalid processed_byte ${processedByte}`
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const confirmedProcessedByte =
|
|
187
|
+
Number.isFinite(processedByte) && processedByte > offset
|
|
188
|
+
? processedByte
|
|
189
|
+
: startOffset + written;
|
|
190
|
+
if (typeof this.postMessage === 'function') {
|
|
191
|
+
const elapsedMs = Date.now() - startTime;
|
|
192
|
+
const transferredBytes = Math.min(written, dataLength);
|
|
193
|
+
this.postMessage(
|
|
194
|
+
createUiMessage(UI_REQUEST.DEVICE_PROGRESS, {
|
|
195
|
+
progress: getConfirmedProgress(confirmedProcessedByte, totalSize, written, dataLength),
|
|
196
|
+
transferredBytes,
|
|
197
|
+
totalBytes: dataLength,
|
|
198
|
+
rateBytesPerSecond:
|
|
199
|
+
elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
|
|
200
|
+
elapsedMs,
|
|
201
|
+
})
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
chunkIndex += 1;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return Promise.resolve({
|
|
208
|
+
...lastMessage,
|
|
209
|
+
path: this.params.path,
|
|
210
|
+
offset: startOffset,
|
|
211
|
+
total_size: totalSize,
|
|
212
|
+
processed_byte: startOffset + written,
|
|
213
|
+
chunks: chunkIndex,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -14,7 +14,7 @@ import { uploadFirmware } from './firmware/uploadFirmware';
|
|
|
14
14
|
import { createUiMessage } from '../events';
|
|
15
15
|
import { DeviceModelToTypes, type KnownDevice } from '../types';
|
|
16
16
|
import { isEnteredManuallyBoot } from './firmware/bootloaderHelper';
|
|
17
|
-
import { LoggerNames,
|
|
17
|
+
import { LoggerNames, getDeviceUUID, getLogger, wait } from '../utils';
|
|
18
18
|
import { DataManager } from '../data-manager';
|
|
19
19
|
import { DevicePool } from '../device/DevicePool';
|
|
20
20
|
|
|
@@ -92,7 +92,7 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
|
|
|
92
92
|
true
|
|
93
93
|
);
|
|
94
94
|
await this.device.initialize();
|
|
95
|
-
if (this.device.
|
|
95
|
+
if (this.device.isBootloader()) {
|
|
96
96
|
clearInterval(intervalTimer);
|
|
97
97
|
this.checkPromise?.resolve(true);
|
|
98
98
|
}
|
|
@@ -105,7 +105,7 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
|
|
|
105
105
|
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
106
106
|
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, connectId);
|
|
107
107
|
|
|
108
|
-
if (deviceList.length === 1 && deviceList[0]?.
|
|
108
|
+
if (deviceList.length === 1 && deviceList[0]?.isBootloader()) {
|
|
109
109
|
// should update current device from cache
|
|
110
110
|
// because device was reboot and had some new requests
|
|
111
111
|
this.device.updateFromCache(deviceList[0]);
|
|
@@ -131,9 +131,17 @@ export default class FirmwareUpdate extends BaseMethod<Params> {
|
|
|
131
131
|
async run() {
|
|
132
132
|
const { device, params } = this;
|
|
133
133
|
const { features, commands } = device;
|
|
134
|
-
const deviceType =
|
|
134
|
+
const deviceType = device.getCurrentDeviceType();
|
|
135
|
+
|
|
136
|
+
// Protocol V2 (Pro2) 固件升级走 DeviceFirmwareUpdate 流程,禁止进入 legacy 入口
|
|
137
|
+
if (device.isProtocolV2()) {
|
|
138
|
+
throw ERRORS.TypedError(
|
|
139
|
+
HardwareErrorCode.RuntimeError,
|
|
140
|
+
'Protocol V2 firmware update must use firmwareUpdateV4'
|
|
141
|
+
);
|
|
142
|
+
}
|
|
135
143
|
|
|
136
|
-
if (!
|
|
144
|
+
if (!device.isBootloader() && features) {
|
|
137
145
|
const uuid = getDeviceUUID(features);
|
|
138
146
|
// should go to bootloader mode manually
|
|
139
147
|
if (isEnteredManuallyBoot(features, params.updateType)) {
|