@onetokenfe/hd-core 1.1.23
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/.eslintrc +6 -0
- package/README.md +32 -0
- package/__tests__/benfen.test.ts +68 -0
- package/__tests__/checkBootloaderReleast.test.ts +115 -0
- package/__tests__/evmSignTransaction.test.ts +419 -0
- package/jest.config.js +6 -0
- package/package.json +48 -0
- package/src/api/BaseMethod.ts +275 -0
- package/src/api/CheckAllFirmwareRelease.ts +73 -0
- package/src/api/CheckBLEFirmwareRelease.ts +23 -0
- package/src/api/CheckBootloaderRelease.ts +32 -0
- package/src/api/CheckBridgeRelease.ts +28 -0
- package/src/api/CheckBridgeStatus.ts +32 -0
- package/src/api/CheckFirmwareRelease.ts +31 -0
- package/src/api/CheckFirmwareTypeAvailable.tsx +30 -0
- package/src/api/CipherKeyValue.ts +68 -0
- package/src/api/FirmwareUpdate.ts +219 -0
- package/src/api/FirmwareUpdateV2.ts +408 -0
- package/src/api/FirmwareUpdateV3.ts +560 -0
- package/src/api/GetFeatures.ts +23 -0
- package/src/api/GetLogs.ts +40 -0
- package/src/api/GetOnetokenFeatures.ts +25 -0
- package/src/api/GetPassphraseState.ts +28 -0
- package/src/api/PromptWebDeviceAccess.ts +77 -0
- package/src/api/SearchDevices.ts +50 -0
- package/src/api/alephium/AlephiumGetAddress.ts +84 -0
- package/src/api/alephium/AlephiumSignMessage.ts +51 -0
- package/src/api/alephium/AlephiumSignTransaction.ts +135 -0
- package/src/api/algo/AlgoGetAddress.ts +73 -0
- package/src/api/algo/AlgoSignTransaction.ts +52 -0
- package/src/api/allnetwork/AllNetworkGetAddress.ts +88 -0
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +529 -0
- package/src/api/allnetwork/AllNetworkGetAddressByLoop.ts +162 -0
- package/src/api/aptos/AptosGetAddress.ts +129 -0
- package/src/api/aptos/AptosGetPublicKey.ts +64 -0
- package/src/api/aptos/AptosSignInMessage.ts +55 -0
- package/src/api/aptos/AptosSignMessage.ts +79 -0
- package/src/api/aptos/AptosSignTransaction.ts +72 -0
- package/src/api/benfen/BenfenGetAddress.ts +122 -0
- package/src/api/benfen/BenfenGetPublicKey.ts +68 -0
- package/src/api/benfen/BenfenSignMessage.ts +50 -0
- package/src/api/benfen/BenfenSignTransaction.ts +105 -0
- package/src/api/benfen/normalize.ts +51 -0
- package/src/api/btc/BTCGetAddress.ts +91 -0
- package/src/api/btc/BTCGetPublicKey.ts +174 -0
- package/src/api/btc/BTCSignMessage.ts +73 -0
- package/src/api/btc/BTCSignPsbt.ts +65 -0
- package/src/api/btc/BTCSignTransaction.ts +148 -0
- package/src/api/btc/BTCVerifyMessage.ts +46 -0
- package/src/api/btc/helpers/btcParamsUtils.ts +64 -0
- package/src/api/btc/helpers/signtx.ts +251 -0
- package/src/api/btc/helpers/signtxLegacy.ts +227 -0
- package/src/api/btc/helpers/versionLimit.ts +25 -0
- package/src/api/btc/helpers/xpubUtils.ts +132 -0
- package/src/api/cardano/CardanoGetAddress.ts +139 -0
- package/src/api/cardano/CardanoGetPublicKey.ts +72 -0
- package/src/api/cardano/CardanoSignMessage.ts +73 -0
- package/src/api/cardano/CardanoSignTransaction.ts +404 -0
- package/src/api/cardano/helper/addressParameters.ts +120 -0
- package/src/api/cardano/helper/auxiliaryData.ts +133 -0
- package/src/api/cardano/helper/cardanoInputs.ts +55 -0
- package/src/api/cardano/helper/cardanoOutputs.ts +89 -0
- package/src/api/cardano/helper/certificate.ts +246 -0
- package/src/api/cardano/helper/token.ts +44 -0
- package/src/api/cardano/helper/utils.ts +17 -0
- package/src/api/cardano/helper/witnesses.ts +62 -0
- package/src/api/conflux/ConfluxGetAddress.ts +78 -0
- package/src/api/conflux/ConfluxSignMessage.ts +49 -0
- package/src/api/conflux/ConfluxSignMessageCIP23.ts +49 -0
- package/src/api/conflux/ConfluxSignTransaction.ts +135 -0
- package/src/api/cosmos/CosmosGetAddress.ts +80 -0
- package/src/api/cosmos/CosmosGetPublicKey.ts +77 -0
- package/src/api/cosmos/CosmosSignTransaction.ts +68 -0
- package/src/api/device/DeviceBackup.ts +15 -0
- package/src/api/device/DeviceCancel.ts +15 -0
- package/src/api/device/DeviceChangePin.ts +25 -0
- package/src/api/device/DeviceFlags.ts +26 -0
- package/src/api/device/DeviceFullyUploadResource.ts +80 -0
- package/src/api/device/DeviceLock.ts +15 -0
- package/src/api/device/DeviceRebootToBoardloader.ts +30 -0
- package/src/api/device/DeviceRebootToBootloader.ts +28 -0
- package/src/api/device/DeviceRecovery.ts +44 -0
- package/src/api/device/DeviceReset.ts +46 -0
- package/src/api/device/DeviceSettings.ts +96 -0
- package/src/api/device/DeviceSupportFeatures.ts +29 -0
- package/src/api/device/DeviceUnlock.ts +13 -0
- package/src/api/device/DeviceUpdateBootloader.ts +111 -0
- package/src/api/device/DeviceUpdateReboot.ts +17 -0
- package/src/api/device/DeviceUploadResource.ts +204 -0
- package/src/api/device/DeviceVerify.ts +65 -0
- package/src/api/device/DeviceWipe.ts +15 -0
- package/src/api/dynex/DnxGetAddress.ts +75 -0
- package/src/api/dynex/DnxSignTransaction.ts +126 -0
- package/src/api/evm/EVMGetAddress.ts +88 -0
- package/src/api/evm/EVMGetPublicKey.ts +116 -0
- package/src/api/evm/EVMSignMessage.ts +49 -0
- package/src/api/evm/EVMSignMessageEIP712.ts +56 -0
- package/src/api/evm/EVMSignTransaction.ts +141 -0
- package/src/api/evm/EVMSignTypedData.ts +477 -0
- package/src/api/evm/EVMVerifyMessage.ts +46 -0
- package/src/api/evm/latest/getAddress.ts +13 -0
- package/src/api/evm/latest/getPublicKey.ts +17 -0
- package/src/api/evm/latest/signMessage.ts +19 -0
- package/src/api/evm/latest/signTransaction.ts +303 -0
- package/src/api/evm/latest/signTypedData.ts +34 -0
- package/src/api/evm/latest/signTypedHash.ts +46 -0
- package/src/api/evm/latest/verifyMessage.ts +15 -0
- package/src/api/evm/legacyV1/getAddress.ts +16 -0
- package/src/api/evm/legacyV1/getPublicKey.ts +20 -0
- package/src/api/evm/legacyV1/signMessage.ts +22 -0
- package/src/api/evm/legacyV1/signTransaction.ts +37 -0
- package/src/api/evm/legacyV1/signTypedData.ts +37 -0
- package/src/api/evm/legacyV1/signTypedHash.ts +50 -0
- package/src/api/evm/legacyV1/verifyMessage.ts +19 -0
- package/src/api/filecoin/FilecoinGetAddress.ts +80 -0
- package/src/api/filecoin/FilecoinSignTransaction.ts +57 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +476 -0
- package/src/api/firmware/bootloaderHelper.ts +46 -0
- package/src/api/firmware/getBinary.ts +99 -0
- package/src/api/firmware/releaseHelper.ts +78 -0
- package/src/api/firmware/updateBootloader.ts +82 -0
- package/src/api/firmware/uploadFirmware.ts +541 -0
- package/src/api/helpers/batchGetPublickeys.ts +84 -0
- package/src/api/helpers/bigNumberUtils.ts +58 -0
- package/src/api/helpers/hexUtils.ts +111 -0
- package/src/api/helpers/paramsValidator.ts +165 -0
- package/src/api/helpers/pathUtils.ts +145 -0
- package/src/api/helpers/stringUtils.ts +11 -0
- package/src/api/helpers/typeNameUtils.ts +137 -0
- package/src/api/index.ts +161 -0
- package/src/api/kaspa/KaspaGetAddress.ts +103 -0
- package/src/api/kaspa/KaspaSignTransaction.ts +182 -0
- package/src/api/kaspa/helpers/BufferWriter.ts +177 -0
- package/src/api/kaspa/helpers/HashWriter.ts +74 -0
- package/src/api/kaspa/helpers/SignatureType.ts +7 -0
- package/src/api/kaspa/helpers/TransferSerialize.ts +144 -0
- package/src/api/lightning/LnurlAuth.ts +52 -0
- package/src/api/near/NearGetAddress.ts +75 -0
- package/src/api/near/NearSignTransaction.ts +46 -0
- package/src/api/nem/NEMGetAddress.ts +72 -0
- package/src/api/nem/NEMSignTransaction.ts +251 -0
- package/src/api/neo/NeoGetAddress.ts +80 -0
- package/src/api/neo/NeoSignTransaction.ts +59 -0
- package/src/api/nervos/NervosGetAddress.ts +80 -0
- package/src/api/nervos/NervosSignTransaction.ts +116 -0
- package/src/api/nexa/NexaGetAddress.ts +88 -0
- package/src/api/nexa/NexaSignTransaction.ts +107 -0
- package/src/api/nostr/NostrDecryptMessage.ts +57 -0
- package/src/api/nostr/NostrEncryptMessage.ts +57 -0
- package/src/api/nostr/NostrGetPublicKey.ts +74 -0
- package/src/api/nostr/NostrSignEvent.ts +65 -0
- package/src/api/nostr/NostrSignSchnorr.ts +52 -0
- package/src/api/nostr/helper/index.ts +28 -0
- package/src/api/polkadot/PolkadotGetAddress.ts +83 -0
- package/src/api/polkadot/PolkadotSignTransaction.ts +53 -0
- package/src/api/polkadot/networks.ts +72 -0
- package/src/api/scdo/ScdoGetAddress.ts +76 -0
- package/src/api/scdo/ScdoSignMessage.ts +45 -0
- package/src/api/scdo/ScdoSignTransaction.ts +106 -0
- package/src/api/solana/SolGetAddress.ts +68 -0
- package/src/api/solana/SolSignMessage.ts +61 -0
- package/src/api/solana/SolSignOffchainMessage.ts +61 -0
- package/src/api/solana/SolSignTransaction.ts +108 -0
- package/src/api/starcoin/StarcoinGetAddress.ts +69 -0
- package/src/api/starcoin/StarcoinGetPublicKey.ts +70 -0
- package/src/api/starcoin/StarcoinSignMessage.ts +42 -0
- package/src/api/starcoin/StarcoinSignTransaction.ts +38 -0
- package/src/api/starcoin/StarcoinVerifyMessage.ts +35 -0
- package/src/api/stellar/StellarGetAddress.ts +68 -0
- package/src/api/stellar/StellarSignTransaction.ts +220 -0
- package/src/api/sui/SuiGetAddress.ts +117 -0
- package/src/api/sui/SuiGetPublicKey.ts +66 -0
- package/src/api/sui/SuiSignMessage.ts +48 -0
- package/src/api/sui/SuiSignTransaction.ts +126 -0
- package/src/api/sui/normalize.ts +28 -0
- package/src/api/test/TestInitializeDeviceDuration.ts +22 -0
- package/src/api/ton/TonGetAddress.ts +96 -0
- package/src/api/ton/TonSignMessage.ts +217 -0
- package/src/api/ton/TonSignProof.ts +62 -0
- package/src/api/tron/TronGetAddress.ts +75 -0
- package/src/api/tron/TronSignMessage.ts +89 -0
- package/src/api/tron/TronSignTransaction.ts +214 -0
- package/src/api/u2f/GetNextU2FCounter.ts +15 -0
- package/src/api/u2f/SetU2FCounter.ts +19 -0
- package/src/api/utils.ts +23 -0
- package/src/api/xrp/XrpGetAddress.ts +96 -0
- package/src/api/xrp/XrpSignTransaction.ts +71 -0
- package/src/constants/errors.ts +15 -0
- package/src/constants/index.ts +2 -0
- package/src/constants/ui-request.ts +3 -0
- package/src/core/RequestQueue.ts +134 -0
- package/src/core/index.ts +1320 -0
- package/src/data/coins/bitcoin.json +44 -0
- package/src/data/config.ts +25 -0
- package/src/data/messages/messages.json +13167 -0
- package/src/data/messages/messages_legacy_v1.json +10282 -0
- package/src/data-manager/CoinManager.ts +31 -0
- package/src/data-manager/DataManager.ts +499 -0
- package/src/data-manager/MessagesConfig.ts +28 -0
- package/src/data-manager/TransportManager.ts +140 -0
- package/src/data-manager/connectSettings.ts +121 -0
- package/src/data-manager/index.ts +3 -0
- package/src/device/Device.ts +884 -0
- package/src/device/DeviceCommands.ts +631 -0
- package/src/device/DeviceConnector.ts +124 -0
- package/src/device/DeviceList.ts +39 -0
- package/src/device/DevicePool.ts +266 -0
- package/src/events/call.ts +95 -0
- package/src/events/core.ts +65 -0
- package/src/events/device.ts +92 -0
- package/src/events/firmware.ts +43 -0
- package/src/events/iframe.ts +55 -0
- package/src/events/index.ts +10 -0
- package/src/events/log.ts +23 -0
- package/src/events/logBlockEvent.ts +6 -0
- package/src/events/ui-promise.ts +14 -0
- package/src/events/ui-request.ts +216 -0
- package/src/events/ui-response.ts +59 -0
- package/src/events/utils.ts +19 -0
- package/src/index.ts +70 -0
- package/src/inject.ts +408 -0
- package/src/lowLevelInject.ts +61 -0
- package/src/topLevelInject.ts +62 -0
- package/src/types/api/alephiumGetAddress.ts +31 -0
- package/src/types/api/alephiumSignMessage.ts +14 -0
- package/src/types/api/alephiumSignTransaction.ts +18 -0
- package/src/types/api/algoGetAddress.ts +23 -0
- package/src/types/api/algoSignTransaction.ts +17 -0
- package/src/types/api/allNetworkGetAddress.ts +130 -0
- package/src/types/api/aptosGetAddress.ts +28 -0
- package/src/types/api/aptosGetPublicKey.ts +27 -0
- package/src/types/api/aptosSignInMessage.ts +17 -0
- package/src/types/api/aptosSignMessage.ts +26 -0
- package/src/types/api/aptosSignTransaction.ts +18 -0
- package/src/types/api/benfenGetAddress.ts +24 -0
- package/src/types/api/benfenGetPublicKey.ts +23 -0
- package/src/types/api/benfenSignMessage.ts +13 -0
- package/src/types/api/benfenSignTransaction.ts +19 -0
- package/src/types/api/btcGetAddress.ts +26 -0
- package/src/types/api/btcGetPublicKey.ts +26 -0
- package/src/types/api/btcSignMessage.ts +16 -0
- package/src/types/api/btcSignPsbt.ts +13 -0
- package/src/types/api/btcSignTransaction.ts +98 -0
- package/src/types/api/btcVerifyMessage.ts +15 -0
- package/src/types/api/cardano.ts +212 -0
- package/src/types/api/cardanoGetAddress.ts +49 -0
- package/src/types/api/cardanoGetPublicKey.ts +33 -0
- package/src/types/api/cardanoSignMessage.ts +31 -0
- package/src/types/api/cardanoSignTransaction.ts +8 -0
- package/src/types/api/checkAllFirmwareRelease.ts +34 -0
- package/src/types/api/checkBLEFirmwareRelease.ts +15 -0
- package/src/types/api/checkBootloaderRelease.ts +19 -0
- package/src/types/api/checkBridgeRelease.ts +14 -0
- package/src/types/api/checkBridgeStatus.ts +3 -0
- package/src/types/api/checkFirmwareRelease.ts +23 -0
- package/src/types/api/checkFirmwareTypeAvailable.ts +12 -0
- package/src/types/api/cipherKeyValue.ts +28 -0
- package/src/types/api/confluxGetAddress.ts +24 -0
- package/src/types/api/confluxSignMessage.ts +13 -0
- package/src/types/api/confluxSignMessageCIP23.ts +14 -0
- package/src/types/api/confluxSignTransaction.ts +32 -0
- package/src/types/api/cosmosGetAddress.ts +24 -0
- package/src/types/api/cosmosGetPublicKey.ts +28 -0
- package/src/types/api/cosmosSignTransaction.ts +17 -0
- package/src/types/api/deviceBackup.ts +4 -0
- package/src/types/api/deviceCancel.ts +4 -0
- package/src/types/api/deviceChangePin.ts +11 -0
- package/src/types/api/deviceFlags.ts +11 -0
- package/src/types/api/deviceFullyUploadResource.ts +15 -0
- package/src/types/api/deviceLock.ts +4 -0
- package/src/types/api/deviceRebootToBoardloader.ts +6 -0
- package/src/types/api/deviceRebootToBootloader.ts +4 -0
- package/src/types/api/deviceRecovery.ts +19 -0
- package/src/types/api/deviceReset.ts +20 -0
- package/src/types/api/deviceSettings.ts +23 -0
- package/src/types/api/deviceSupportFeatures.ts +6 -0
- package/src/types/api/deviceUnlock.ts +4 -0
- package/src/types/api/deviceUpdateBootloader.ts +13 -0
- package/src/types/api/deviceUpdateReboot.ts +3 -0
- package/src/types/api/deviceUploadResource.ts +21 -0
- package/src/types/api/deviceVerify.ts +15 -0
- package/src/types/api/deviceWipe.ts +4 -0
- package/src/types/api/dnxGetAddress.ts +23 -0
- package/src/types/api/dnxSignTransaction.ts +36 -0
- package/src/types/api/event.ts +8 -0
- package/src/types/api/evmGetAddress.ts +24 -0
- package/src/types/api/evmGetPublicKey.ts +36 -0
- package/src/types/api/evmSignMessage.ts +14 -0
- package/src/types/api/evmSignMessageEIP712.ts +14 -0
- package/src/types/api/evmSignTransaction.ts +80 -0
- package/src/types/api/evmSignTypedData.ts +42 -0
- package/src/types/api/evmVerifyMessage.ts +15 -0
- package/src/types/api/export.ts +194 -0
- package/src/types/api/filecoinGetAddress.ts +24 -0
- package/src/types/api/filecoinSignTransaction.ts +24 -0
- package/src/types/api/firmwareUpdate.ts +66 -0
- package/src/types/api/getFeatures.ts +4 -0
- package/src/types/api/getLogs.ts +3 -0
- package/src/types/api/getNextU2FCounter.ts +7 -0
- package/src/types/api/getOnetokenFeatures.ts +7 -0
- package/src/types/api/getPassphraseState.ts +6 -0
- package/src/types/api/index.ts +404 -0
- package/src/types/api/init.ts +11 -0
- package/src/types/api/kaspaGetAddress.ts +26 -0
- package/src/types/api/kaspaSignTransaction.ts +44 -0
- package/src/types/api/lnurlAuth.ts +22 -0
- package/src/types/api/nearGetAddress.ts +23 -0
- package/src/types/api/nearSignTransaction.ts +13 -0
- package/src/types/api/nemGetAddress.ts +24 -0
- package/src/types/api/nemSignTransaction.ts +118 -0
- package/src/types/api/neoGetAddress.ts +24 -0
- package/src/types/api/neoSignTransaction.ts +18 -0
- package/src/types/api/nervosGetAddress.ts +24 -0
- package/src/types/api/nervosSignTransaction.ts +19 -0
- package/src/types/api/nexaGetAddress.ts +26 -0
- package/src/types/api/nexaSignTransaction.ts +28 -0
- package/src/types/api/nostrDecryptMessage.ts +25 -0
- package/src/types/api/nostrEncryptMessage.ts +25 -0
- package/src/types/api/nostrGetPublicKey.ts +28 -0
- package/src/types/api/nostrSignEvent.ts +52 -0
- package/src/types/api/nostrSignSchnorr.ts +22 -0
- package/src/types/api/polkadotGetAddress.ts +30 -0
- package/src/types/api/polkadotSignTransaction.ts +19 -0
- package/src/types/api/promptWebDeviceAccess.ts +6 -0
- package/src/types/api/scdoGetAddress.ts +23 -0
- package/src/types/api/scdoSignMessage.ts +13 -0
- package/src/types/api/scdoSignTransaction.ts +24 -0
- package/src/types/api/searchDevices.ts +4 -0
- package/src/types/api/setU2FCounter.ts +7 -0
- package/src/types/api/solGetAddress.ts +23 -0
- package/src/types/api/solSignMessage.ts +17 -0
- package/src/types/api/solSignOffchainMessage.ts +24 -0
- package/src/types/api/solSignTransaction.ts +27 -0
- package/src/types/api/starcoinGetAddress.ts +23 -0
- package/src/types/api/starcoinGetPublicKey.ts +23 -0
- package/src/types/api/starcoinSignMessage.ts +13 -0
- package/src/types/api/starcoinSignTransaction.ts +13 -0
- package/src/types/api/starcoinVerifyMessage.ts +14 -0
- package/src/types/api/stellarGetAddress.ts +23 -0
- package/src/types/api/stellarSignTransaction.ts +154 -0
- package/src/types/api/suiGetAddress.ts +28 -0
- package/src/types/api/suiGetPublicKey.ts +27 -0
- package/src/types/api/suiSignMessage.ts +13 -0
- package/src/types/api/suiSignTransaction.ts +17 -0
- package/src/types/api/testInitializeDeviceDuration.ts +6 -0
- package/src/types/api/tonGetAddress.ts +34 -0
- package/src/types/api/tonSignMessage.ts +42 -0
- package/src/types/api/tonSignProof.ts +25 -0
- package/src/types/api/tronGetAddress.ts +23 -0
- package/src/types/api/tronSignMessage.ts +14 -0
- package/src/types/api/tronSignTransaction.ts +89 -0
- package/src/types/api/uiResponse.ts +3 -0
- package/src/types/api/xrpGetAddress.ts +28 -0
- package/src/types/api/xrpSignTransaction.ts +29 -0
- package/src/types/device.ts +194 -0
- package/src/types/firmware.ts +41 -0
- package/src/types/global.d.ts +3 -0
- package/src/types/index.ts +5 -0
- package/src/types/params.ts +64 -0
- package/src/types/settings.ts +144 -0
- package/src/utils/arrayUtils.ts +7 -0
- package/src/utils/assets.ts +5 -0
- package/src/utils/bridgeUpdate.ts +80 -0
- package/src/utils/capabilitieUtils.ts +12 -0
- package/src/utils/deviceFeaturesUtils.ts +352 -0
- package/src/utils/deviceInfoUtils.ts +167 -0
- package/src/utils/deviceSettings.ts +109 -0
- package/src/utils/deviceVersionUtils.ts +79 -0
- package/src/utils/findDefectiveBatchDevice.ts +39 -0
- package/src/utils/getMutex.ts +41 -0
- package/src/utils/getSynchronize.ts +25 -0
- package/src/utils/homescreen.ts +345 -0
- package/src/utils/index.ts +44 -0
- package/src/utils/logger.ts +190 -0
- package/src/utils/networkUtils.ts +25 -0
- package/src/utils/patch.ts +14 -0
- package/src/utils/promiseUtils.ts +4 -0
- package/src/utils/release.ts +42 -0
- package/src/utils/semver.test.js +53 -0
- package/src/utils/tracing.ts +238 -0
- package/src/utils/versionUtils.ts +120 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onetokenfe/hd-shared';
|
|
2
|
+
import semver from 'semver';
|
|
3
|
+
import JSZip from 'jszip';
|
|
4
|
+
|
|
5
|
+
import { FirmwareUpdateTipMessage, UI_REQUEST } from '../events/ui-request';
|
|
6
|
+
import { validateParams } from './helpers/paramsValidator';
|
|
7
|
+
import {
|
|
8
|
+
LoggerNames,
|
|
9
|
+
getDeviceBLEFirmwareVersion,
|
|
10
|
+
getDeviceBootloaderVersion,
|
|
11
|
+
getDeviceFirmwareVersion,
|
|
12
|
+
getDeviceType,
|
|
13
|
+
getFirmwareType,
|
|
14
|
+
getLogger,
|
|
15
|
+
} from '../utils';
|
|
16
|
+
import { getBinary, getSysResourceBinary } from './firmware/getBinary';
|
|
17
|
+
import { DataManager } from '../data-manager';
|
|
18
|
+
import { FirmwareUpdateBaseMethod } from './firmware/FirmwareUpdateBaseMethod';
|
|
19
|
+
import { DevicePool } from '../device/DevicePool';
|
|
20
|
+
import { DEVICE } from '../events';
|
|
21
|
+
|
|
22
|
+
import type { FirmwareUpdateV3Params } from '../types/api/firmwareUpdate';
|
|
23
|
+
import type { Deferred, EFirmwareType } from '@onetokenfe/hd-shared';
|
|
24
|
+
import type { TypedResponseMessage } from '../device/DeviceCommands';
|
|
25
|
+
|
|
26
|
+
const Log = getLogger(LoggerNames.Method);
|
|
27
|
+
|
|
28
|
+
export const MIN_UPDATE_V3_BOOTLOADER_VERSION = '2.8.0';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* FirmwareUpdateV3 flow
|
|
32
|
+
1. StartDownloadFirmware
|
|
33
|
+
2. FinishDownloadFirmware
|
|
34
|
+
3. AutoRebootToBootloader
|
|
35
|
+
4. GoToBootloaderSuccess
|
|
36
|
+
5. StartTransferData
|
|
37
|
+
6. ConfirmOnDevice
|
|
38
|
+
7. FirmwareUpdating
|
|
39
|
+
8. FirmwareUpdateCompleted
|
|
40
|
+
*/
|
|
41
|
+
export default class FirmwareUpdateV3 extends FirmwareUpdateBaseMethod<FirmwareUpdateV3Params> {
|
|
42
|
+
checkPromise: Deferred<any> | null = null;
|
|
43
|
+
|
|
44
|
+
private isSwitchFirmware = false;
|
|
45
|
+
|
|
46
|
+
init() {
|
|
47
|
+
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
48
|
+
this.requireDeviceMode = [];
|
|
49
|
+
this.useDevicePassphraseState = false;
|
|
50
|
+
this.skipForceUpdateCheck = true;
|
|
51
|
+
|
|
52
|
+
const { payload } = this;
|
|
53
|
+
|
|
54
|
+
validateParams(payload, [
|
|
55
|
+
{ name: 'bleVersion', type: 'array' },
|
|
56
|
+
{ name: 'bleBinary', type: 'buffer' },
|
|
57
|
+
{ name: 'firmwareVersion', type: 'array' },
|
|
58
|
+
{ name: 'firmwareBinary', type: 'buffer' },
|
|
59
|
+
{ name: 'resourceBinary', type: 'buffer' },
|
|
60
|
+
{ name: 'forcedUpdateRes', type: 'boolean' },
|
|
61
|
+
{ name: 'bootloaderVersion', type: 'array' },
|
|
62
|
+
{ name: 'bootloaderBinary', type: 'buffer' },
|
|
63
|
+
{ name: 'firmwareType', type: 'string' },
|
|
64
|
+
{ name: 'platform', type: 'string' },
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
this.params = {
|
|
68
|
+
bleBinary: payload.bleBinary,
|
|
69
|
+
firmwareBinary: payload.firmwareBinary,
|
|
70
|
+
forcedUpdateRes: payload.forcedUpdateRes,
|
|
71
|
+
bleVersion: payload.bleVersion,
|
|
72
|
+
bootloaderVersion: payload.bootloaderVersion,
|
|
73
|
+
bootloaderBinary: payload.bootloaderBinary,
|
|
74
|
+
firmwareVersion: payload.firmwareVersion,
|
|
75
|
+
resourceBinary: payload.resourceBinary,
|
|
76
|
+
firmwareType: payload.firmwareType,
|
|
77
|
+
platform: payload.platform,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async run() {
|
|
82
|
+
const { device } = this;
|
|
83
|
+
const { features } = device;
|
|
84
|
+
|
|
85
|
+
const deviceType = getDeviceType(features);
|
|
86
|
+
const bootloaderCurrVersion = getDeviceBootloaderVersion(features).join('.');
|
|
87
|
+
|
|
88
|
+
this.validateDeviceAndVersion(deviceType, bootloaderCurrVersion);
|
|
89
|
+
|
|
90
|
+
if (!features) {
|
|
91
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Device features not available');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const deviceFirmwareType = getFirmwareType(features);
|
|
95
|
+
const firmwareType = this.params.firmwareType ?? deviceFirmwareType;
|
|
96
|
+
this.isSwitchFirmware = firmwareType !== deviceFirmwareType;
|
|
97
|
+
|
|
98
|
+
let resourceBinary: ArrayBuffer | null = null;
|
|
99
|
+
let fwBinaryMap: { fileName: string; binary: ArrayBuffer }[] = [];
|
|
100
|
+
let bootloaderBinary: ArrayBuffer | null = null;
|
|
101
|
+
try {
|
|
102
|
+
this.postTipMessage(FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
103
|
+
resourceBinary = await this.prepareResourceBinary(firmwareType);
|
|
104
|
+
fwBinaryMap = await this.prepareFirmwareAndBleBinary(firmwareType);
|
|
105
|
+
bootloaderBinary = await this.prepareBootloaderBinary(firmwareType);
|
|
106
|
+
this.postTipMessage(FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
107
|
+
} catch (err) {
|
|
108
|
+
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!bootloaderBinary && fwBinaryMap.length === 0) {
|
|
112
|
+
throw ERRORS.TypedError(
|
|
113
|
+
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
114
|
+
'No firmware to update'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
await this.enterBootloaderMode();
|
|
119
|
+
|
|
120
|
+
const updateResult = await this.executeUpdate({
|
|
121
|
+
resourceBinary,
|
|
122
|
+
fwBinaryMap,
|
|
123
|
+
bootloaderBinary,
|
|
124
|
+
});
|
|
125
|
+
return updateResult;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private validateDeviceAndVersion(deviceType: EDeviceType, bootloaderVersion: string) {
|
|
129
|
+
if (deviceType === EDeviceType.Unknown) {
|
|
130
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'unknown device type');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (deviceType !== EDeviceType.Pro) {
|
|
134
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'only pro device is supported');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (semver.lt(bootloaderVersion, MIN_UPDATE_V3_BOOTLOADER_VERSION)) {
|
|
138
|
+
throw ERRORS.TypedError(
|
|
139
|
+
HardwareErrorCode.RuntimeError,
|
|
140
|
+
'bootloader version needs to be updated'
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private async prepareResourceBinary(firmwareType: EFirmwareType) {
|
|
146
|
+
if (this.params.resourceBinary) {
|
|
147
|
+
return this.params.resourceBinary;
|
|
148
|
+
}
|
|
149
|
+
const { features } = this.device;
|
|
150
|
+
if (!features) return null;
|
|
151
|
+
const resourceUrl = DataManager.getSysResourcesLatestRelease({
|
|
152
|
+
features,
|
|
153
|
+
forcedUpdateRes: this.params.forcedUpdateRes,
|
|
154
|
+
firmwareType,
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
if (resourceUrl) {
|
|
158
|
+
const resource = (await getSysResourceBinary(resourceUrl)).binary;
|
|
159
|
+
return resource;
|
|
160
|
+
}
|
|
161
|
+
Log.warn('No resource url found');
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private async prepareBootloaderBinary(firmwareType: EFirmwareType): Promise<ArrayBuffer | null> {
|
|
166
|
+
if (this.params.bootloaderBinary) {
|
|
167
|
+
return this.params.bootloaderBinary;
|
|
168
|
+
}
|
|
169
|
+
const { features } = this.device;
|
|
170
|
+
if (!features) return null;
|
|
171
|
+
|
|
172
|
+
if (this.params.bootloaderVersion) {
|
|
173
|
+
const bootResourceUrl = DataManager.getBootloaderResource(features, firmwareType);
|
|
174
|
+
if (bootResourceUrl) {
|
|
175
|
+
const bootBinary = (await getSysResourceBinary(bootResourceUrl)).binary;
|
|
176
|
+
return bootBinary;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private async prepareFirmwareAndBleBinary(firmwareType: EFirmwareType) {
|
|
183
|
+
const fwBinaryMap: { fileName: string; binary: ArrayBuffer }[] = [];
|
|
184
|
+
if (this.params.firmwareBinary) {
|
|
185
|
+
fwBinaryMap.push({
|
|
186
|
+
fileName: 'firmware.bin',
|
|
187
|
+
binary: this.params.firmwareBinary,
|
|
188
|
+
});
|
|
189
|
+
} else if (this.params.firmwareVersion) {
|
|
190
|
+
const { features } = this.device;
|
|
191
|
+
if (features) {
|
|
192
|
+
const firmwareBinary = (
|
|
193
|
+
await getBinary({
|
|
194
|
+
features,
|
|
195
|
+
version: this.params.firmwareVersion,
|
|
196
|
+
updateType: 'firmware',
|
|
197
|
+
isUpdateBootloader: false,
|
|
198
|
+
firmwareType,
|
|
199
|
+
})
|
|
200
|
+
).binary;
|
|
201
|
+
fwBinaryMap.push({
|
|
202
|
+
fileName: 'firmware.bin',
|
|
203
|
+
binary: firmwareBinary,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (this.params.bleBinary) {
|
|
209
|
+
fwBinaryMap.push({
|
|
210
|
+
fileName: 'ble-firmware.bin',
|
|
211
|
+
binary: this.params.bleBinary,
|
|
212
|
+
});
|
|
213
|
+
} else if (this.params.bleVersion) {
|
|
214
|
+
const { features } = this.device;
|
|
215
|
+
if (features) {
|
|
216
|
+
const bleBinary = await getBinary({
|
|
217
|
+
features,
|
|
218
|
+
version: this.params.bleVersion,
|
|
219
|
+
updateType: 'ble',
|
|
220
|
+
firmwareType,
|
|
221
|
+
});
|
|
222
|
+
fwBinaryMap.push({
|
|
223
|
+
fileName: 'ble-firmware.bin',
|
|
224
|
+
binary: bleBinary.binary,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return fwBinaryMap;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private async executeUpdate({
|
|
232
|
+
resourceBinary,
|
|
233
|
+
fwBinaryMap,
|
|
234
|
+
bootloaderBinary,
|
|
235
|
+
}: {
|
|
236
|
+
resourceBinary: ArrayBuffer | null;
|
|
237
|
+
fwBinaryMap: { fileName: string; binary: ArrayBuffer }[];
|
|
238
|
+
bootloaderBinary: ArrayBuffer | null;
|
|
239
|
+
}) {
|
|
240
|
+
let totalSize = 0;
|
|
241
|
+
let processedSize = 0;
|
|
242
|
+
|
|
243
|
+
if (resourceBinary) {
|
|
244
|
+
totalSize += resourceBinary.byteLength;
|
|
245
|
+
}
|
|
246
|
+
for (const fwbinary of fwBinaryMap) {
|
|
247
|
+
totalSize += fwbinary.binary.byteLength;
|
|
248
|
+
}
|
|
249
|
+
if (bootloaderBinary) {
|
|
250
|
+
totalSize += bootloaderBinary.byteLength;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
this.postTipMessage(FirmwareUpdateTipMessage.StartTransferData);
|
|
254
|
+
// Process resource zip contents
|
|
255
|
+
if (resourceBinary) {
|
|
256
|
+
const file = await JSZip.loadAsync(resourceBinary);
|
|
257
|
+
const files = Object.entries(file.files);
|
|
258
|
+
for (const [fileName, file] of files) {
|
|
259
|
+
const name = fileName.split('/').pop();
|
|
260
|
+
if (!file.dir && fileName.indexOf('__MACOSX') === -1 && name) {
|
|
261
|
+
const data = await file.async('arraybuffer');
|
|
262
|
+
processedSize = await this.emmcCommonUpdateProcess({
|
|
263
|
+
payload: data,
|
|
264
|
+
filePath: `0:res/${name}`,
|
|
265
|
+
processedSize,
|
|
266
|
+
totalSize,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (bootloaderBinary) {
|
|
273
|
+
processedSize = await this.emmcCommonUpdateProcess({
|
|
274
|
+
payload: bootloaderBinary,
|
|
275
|
+
filePath: `0:boot/bootloader.bin`,
|
|
276
|
+
processedSize,
|
|
277
|
+
totalSize,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
await this.createUpdatesFolderIfNotExists(`0:updates/`);
|
|
282
|
+
|
|
283
|
+
for (const fwbinary of fwBinaryMap) {
|
|
284
|
+
if (fwbinary) {
|
|
285
|
+
processedSize = await this.emmcCommonUpdateProcess({
|
|
286
|
+
payload: fwbinary.binary,
|
|
287
|
+
filePath: `0:updates/${fwbinary.fileName}`,
|
|
288
|
+
processedSize,
|
|
289
|
+
totalSize,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// trigger firmware update, support folder updates
|
|
295
|
+
try {
|
|
296
|
+
this.postTipMessage(FirmwareUpdateTipMessage.ConfirmOnDevice);
|
|
297
|
+
await this.startEmmcFirmwareUpdate({
|
|
298
|
+
path: '0:updates',
|
|
299
|
+
});
|
|
300
|
+
} catch (error) {
|
|
301
|
+
Log.error('triggerFirmwareUpdateEmmc error: ', error);
|
|
302
|
+
// Re-throw errors with specific error codes that should not be ignored
|
|
303
|
+
if (error?.errorCode) {
|
|
304
|
+
const unexpectedError = [
|
|
305
|
+
HardwareErrorCode.ActionCancelled,
|
|
306
|
+
HardwareErrorCode.CallQueueActionCancelled,
|
|
307
|
+
HardwareErrorCode.FirmwareVerificationFailed,
|
|
308
|
+
// BLE connection errors
|
|
309
|
+
HardwareErrorCode.BleDeviceNotBonded,
|
|
310
|
+
HardwareErrorCode.BleServiceNotFound,
|
|
311
|
+
HardwareErrorCode.BlePoweredOff,
|
|
312
|
+
HardwareErrorCode.BleUnsupported,
|
|
313
|
+
HardwareErrorCode.BlePermissionError,
|
|
314
|
+
HardwareErrorCode.BleLocationError,
|
|
315
|
+
HardwareErrorCode.BleDeviceBondError,
|
|
316
|
+
HardwareErrorCode.BleCharacteristicNotifyError,
|
|
317
|
+
HardwareErrorCode.BleTimeoutError,
|
|
318
|
+
HardwareErrorCode.BleWriteCharacteristicError,
|
|
319
|
+
// Web device errors
|
|
320
|
+
HardwareErrorCode.WebDeviceNotFoundOrNeedsPermission,
|
|
321
|
+
];
|
|
322
|
+
|
|
323
|
+
if (unexpectedError.includes(error.errorCode)) {
|
|
324
|
+
throw error;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Wrap and re-throw all other errors
|
|
329
|
+
throw ERRORS.TypedError(
|
|
330
|
+
HardwareErrorCode.FirmwareError,
|
|
331
|
+
error?.message || 'Firmware update failed'
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// wait for 1.5s to ensure the device is in update mode
|
|
336
|
+
await wait(1500);
|
|
337
|
+
this.postProcessingMessage('firmware');
|
|
338
|
+
this.postProgressMessage(0, 'installingFirmware');
|
|
339
|
+
// Add timeout of 5 minutes
|
|
340
|
+
const installStartTime = Date.now();
|
|
341
|
+
const maxWaitTimeForInstallingFirmware = 5 * 60 * 1000; // 5 minutes in milliseconds
|
|
342
|
+
|
|
343
|
+
let getFeaturesTimeoutCount = 0;
|
|
344
|
+
const maxGetFeaturesTimeoutBeforeReauth = 3;
|
|
345
|
+
|
|
346
|
+
// eslint-disable-next-line no-constant-condition
|
|
347
|
+
while (true) {
|
|
348
|
+
// Check if timeout exceeded
|
|
349
|
+
if (Date.now() - installStartTime > maxWaitTimeForInstallingFirmware) {
|
|
350
|
+
throw ERRORS.TypedError(
|
|
351
|
+
HardwareErrorCode.RuntimeError,
|
|
352
|
+
'Firmware update process timeout after 5 minutes'
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
try {
|
|
357
|
+
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
358
|
+
const timeoutMs = 3000;
|
|
359
|
+
const featuresRes = await Promise.race<TypedResponseMessage<'Features'>>([
|
|
360
|
+
typedCall('GetFeatures', 'Features', {}),
|
|
361
|
+
new Promise<never>((_, reject) => {
|
|
362
|
+
setTimeout(
|
|
363
|
+
() =>
|
|
364
|
+
reject(
|
|
365
|
+
ERRORS.TypedError(
|
|
366
|
+
HardwareErrorCode.CallMethodNotResponse,
|
|
367
|
+
'GetFeatures timeout',
|
|
368
|
+
{ method: 'GetFeatures', timeoutMs }
|
|
369
|
+
)
|
|
370
|
+
),
|
|
371
|
+
timeoutMs
|
|
372
|
+
);
|
|
373
|
+
}),
|
|
374
|
+
]);
|
|
375
|
+
getFeaturesTimeoutCount = 0;
|
|
376
|
+
const features = featuresRes.message;
|
|
377
|
+
const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
|
|
378
|
+
const bleVersion = getDeviceBLEFirmwareVersion(features).join('.');
|
|
379
|
+
const firmwareVersion = getDeviceFirmwareVersion(features).join('.');
|
|
380
|
+
// Treat update as complete once firmware version becomes non-zero
|
|
381
|
+
if (firmwareVersion !== '0.0.0') {
|
|
382
|
+
this.postTipMessage(FirmwareUpdateTipMessage.FirmwareUpdateCompleted);
|
|
383
|
+
DevicePool.resetState();
|
|
384
|
+
return {
|
|
385
|
+
bootloaderVersion,
|
|
386
|
+
bleVersion,
|
|
387
|
+
firmwareVersion,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
// Still in update mode; continue polling (e.g., iOS may return firmwareVersion 0.0.0 during switches)
|
|
391
|
+
await wait(1000);
|
|
392
|
+
} catch (error) {
|
|
393
|
+
Log.log('getFeatures error', error);
|
|
394
|
+
let shouldReconnect = true;
|
|
395
|
+
const progress = this.extractUpdateModeProgress(error);
|
|
396
|
+
if (progress !== null) {
|
|
397
|
+
getFeaturesTimeoutCount = 0;
|
|
398
|
+
this.postProgressMessage(progress, 'installingFirmware');
|
|
399
|
+
await wait(1000);
|
|
400
|
+
shouldReconnect = false;
|
|
401
|
+
} else if (this.isGetFeaturesTimeoutError(error)) {
|
|
402
|
+
getFeaturesTimeoutCount += 1;
|
|
403
|
+
// Retry transient GetFeatures timeouts to avoid unnecessary WebUSB re-authorization prompts.
|
|
404
|
+
if (getFeaturesTimeoutCount <= maxGetFeaturesTimeoutBeforeReauth) {
|
|
405
|
+
await wait(1000);
|
|
406
|
+
shouldReconnect = false;
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
getFeaturesTimeoutCount = 0;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (shouldReconnect) {
|
|
413
|
+
await wait(1000);
|
|
414
|
+
/**
|
|
415
|
+
* Needs second reconnect case:
|
|
416
|
+
* 1. While including 'Ble firmwware' in ble connect type
|
|
417
|
+
* 2. While including bootloader upgrade
|
|
418
|
+
*/
|
|
419
|
+
const reconnectTimeout =
|
|
420
|
+
this.isBleReconnect() && (this.params.bleBinary || this.params.bleVersion)
|
|
421
|
+
? 3 * 60 * 1000 // 3 minutes for BLE reconnect
|
|
422
|
+
: 60 * 1000; // 1 minute for normal reconnect
|
|
423
|
+
|
|
424
|
+
getFeaturesTimeoutCount = 0;
|
|
425
|
+
await this.waitForDeviceReconnect(reconnectTimeout);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Parse “Update mode XX” progress value from device errors to avoid hardcoded message.includes.
|
|
433
|
+
*/
|
|
434
|
+
private extractUpdateModeProgress(error: unknown): number | null {
|
|
435
|
+
const message = this.normalizeErrorMessage(error);
|
|
436
|
+
if (!message) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
const match = message.match(/Update mode\s*(\d+)/i);
|
|
440
|
+
if (!match) {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
const progress = parseInt(match[1], 10);
|
|
444
|
+
return Number.isNaN(progress) ? null : progress;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
private isGetFeaturesTimeoutError(error: unknown): boolean {
|
|
448
|
+
return (
|
|
449
|
+
error instanceof HardwareError &&
|
|
450
|
+
error.errorCode === HardwareErrorCode.CallMethodNotResponse &&
|
|
451
|
+
error.params?.method === 'GetFeatures'
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
private normalizeErrorMessage(error: unknown): string {
|
|
456
|
+
if (!error) {
|
|
457
|
+
return '';
|
|
458
|
+
}
|
|
459
|
+
if (typeof error === 'string') {
|
|
460
|
+
return error;
|
|
461
|
+
}
|
|
462
|
+
if (typeof error === 'object') {
|
|
463
|
+
const { message } = error as { message?: unknown };
|
|
464
|
+
if (typeof message === 'string') {
|
|
465
|
+
return message;
|
|
466
|
+
}
|
|
467
|
+
if (message !== undefined && message !== null) {
|
|
468
|
+
return String(message);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return '';
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
private canPromptWebUsbSwitchFirmwareReconnect(): boolean {
|
|
475
|
+
if (!this.isSwitchFirmware) {
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
return (
|
|
479
|
+
DataManager.isBrowserWebUsb(DataManager.getSettings('env')) &&
|
|
480
|
+
!this.payload.skipWebDevicePrompt &&
|
|
481
|
+
this.device.listenerCount(DEVICE.SELECT_DEVICE_FOR_SWITCH_FIRMWARE_WEB_DEVICE) > 0
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* @description Reconnect device - While update with bootloader, it will reconnect device
|
|
487
|
+
* @param {number} timeout - The timeout for the reconnection
|
|
488
|
+
*/
|
|
489
|
+
async waitForDeviceReconnect(timeout: number) {
|
|
490
|
+
const startTime = Date.now();
|
|
491
|
+
const isBleReconnect = this.isBleReconnect();
|
|
492
|
+
let webUsbCheckCount = 0;
|
|
493
|
+
while (Date.now() - startTime < timeout) {
|
|
494
|
+
try {
|
|
495
|
+
if (isBleReconnect) {
|
|
496
|
+
try {
|
|
497
|
+
await this.device.deviceConnector?.acquire(
|
|
498
|
+
this.device.originalDescriptor.id,
|
|
499
|
+
null,
|
|
500
|
+
true
|
|
501
|
+
);
|
|
502
|
+
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
503
|
+
await Promise.race([
|
|
504
|
+
typedCall('Initialize', 'Features', {}),
|
|
505
|
+
new Promise((_, reject) => {
|
|
506
|
+
setTimeout(() => {
|
|
507
|
+
reject(ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed));
|
|
508
|
+
}, 3000);
|
|
509
|
+
}),
|
|
510
|
+
]);
|
|
511
|
+
return;
|
|
512
|
+
} catch (e) {
|
|
513
|
+
// ignore error because of device is not connected
|
|
514
|
+
Log.log('catch Bluetooth error when device is restarting: ', e);
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
const deviceDiff = await this.device.deviceConnector?.enumerate();
|
|
518
|
+
const devicesDescriptor = deviceDiff?.descriptors ?? [];
|
|
519
|
+
|
|
520
|
+
const canPromptSwitchFirmwareReconnect = this.canPromptWebUsbSwitchFirmwareReconnect();
|
|
521
|
+
|
|
522
|
+
if (canPromptSwitchFirmwareReconnect) {
|
|
523
|
+
webUsbCheckCount += 1;
|
|
524
|
+
if (webUsbCheckCount > 4) {
|
|
525
|
+
this.postTipMessage(FirmwareUpdateTipMessage.SwitchFirmwareReconnectDevice);
|
|
526
|
+
try {
|
|
527
|
+
await this._promptDeviceForSwitchFirmwareWebDevice();
|
|
528
|
+
} catch (e) {
|
|
529
|
+
Log.log('WebUSB re-authorization failed: ', e);
|
|
530
|
+
}
|
|
531
|
+
webUsbCheckCount = 0;
|
|
532
|
+
}
|
|
533
|
+
} else {
|
|
534
|
+
webUsbCheckCount = 0;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, this.connectId);
|
|
538
|
+
|
|
539
|
+
if (deviceList.length === 1) {
|
|
540
|
+
this.device.updateFromCache(deviceList[0]);
|
|
541
|
+
await this.device.acquire();
|
|
542
|
+
this.device.commands.disposed = false;
|
|
543
|
+
this.device.getCommands().mainId = this.device.mainId ?? '';
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
await wait(1000);
|
|
548
|
+
} catch (error) {
|
|
549
|
+
console.error('Device reconnect failed: ', error);
|
|
550
|
+
Log.error('Device reconnect failed:', error);
|
|
551
|
+
await wait(1000);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
throw ERRORS.TypedError(
|
|
556
|
+
HardwareErrorCode.DeviceNotFound,
|
|
557
|
+
`Device not reconnected within ${timeout / 1000}s`
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ERRORS, HardwareErrorCode } from '@onetokenfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import { UI_REQUEST } from '../constants/ui-request';
|
|
4
|
+
import { BaseMethod } from './BaseMethod';
|
|
5
|
+
|
|
6
|
+
export default class GetFeatures extends BaseMethod {
|
|
7
|
+
init() {
|
|
8
|
+
this.allowDeviceMode = [
|
|
9
|
+
...this.allowDeviceMode,
|
|
10
|
+
UI_REQUEST.NOT_INITIALIZE,
|
|
11
|
+
UI_REQUEST.BOOTLOADER,
|
|
12
|
+
];
|
|
13
|
+
this.useDevicePassphraseState = false;
|
|
14
|
+
this.skipForceUpdateCheck = true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
run() {
|
|
18
|
+
if (this.payload?.detectBootloaderDevice && this.device.features?.bootloader_mode) {
|
|
19
|
+
return Promise.reject(ERRORS.TypedError(HardwareErrorCode.DeviceDetectInBootloaderMode));
|
|
20
|
+
}
|
|
21
|
+
return Promise.resolve(this.device.features);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BaseMethod } from './BaseMethod';
|
|
2
|
+
import { getLog } from '../utils';
|
|
3
|
+
|
|
4
|
+
export default class GetLogs extends BaseMethod {
|
|
5
|
+
init() {
|
|
6
|
+
this.useDevice = false;
|
|
7
|
+
this.useDevicePassphraseState = false;
|
|
8
|
+
this.skipForceUpdateCheck = true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
serializeLog({
|
|
12
|
+
level,
|
|
13
|
+
prefix,
|
|
14
|
+
message,
|
|
15
|
+
timestamp,
|
|
16
|
+
}: {
|
|
17
|
+
level: string;
|
|
18
|
+
prefix: string;
|
|
19
|
+
message: any[];
|
|
20
|
+
timestamp: number;
|
|
21
|
+
}) {
|
|
22
|
+
const date = new Date(timestamp).toISOString();
|
|
23
|
+
|
|
24
|
+
const messageString = message
|
|
25
|
+
.map(item => {
|
|
26
|
+
if (typeof item === 'object') {
|
|
27
|
+
return JSON.stringify(item);
|
|
28
|
+
}
|
|
29
|
+
return String(item);
|
|
30
|
+
})
|
|
31
|
+
.join(' ');
|
|
32
|
+
|
|
33
|
+
return `[${date}] ${level.toUpperCase()} ${prefix}: ${messageString}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async run() {
|
|
37
|
+
const logs = getLog().map(log => this.serializeLog(log));
|
|
38
|
+
return Promise.resolve(logs);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import semver from 'semver';
|
|
2
|
+
|
|
3
|
+
import { UI_REQUEST } from '../constants/ui-request';
|
|
4
|
+
import { fixVersion } from '../utils/deviceFeaturesUtils';
|
|
5
|
+
import { BaseMethod } from './BaseMethod';
|
|
6
|
+
|
|
7
|
+
export default class Getonetokenfeatures extends BaseMethod {
|
|
8
|
+
init() {
|
|
9
|
+
this.allowDeviceMode = [
|
|
10
|
+
...this.allowDeviceMode,
|
|
11
|
+
UI_REQUEST.NOT_INITIALIZE,
|
|
12
|
+
UI_REQUEST.BOOTLOADER,
|
|
13
|
+
];
|
|
14
|
+
this.useDevicePassphraseState = false;
|
|
15
|
+
this.skipForceUpdateCheck = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async run() {
|
|
19
|
+
const { message } = await this.device.commands.typedCall('OnetokenGetFeatures', 'onetokenfeatures');
|
|
20
|
+
if (!!message.onetoken_firmware_version && !semver.valid(message.onetoken_firmware_version)) {
|
|
21
|
+
message.onetoken_firmware_version = fixVersion(message.onetoken_firmware_version);
|
|
22
|
+
}
|
|
23
|
+
return Promise.resolve(message);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ERRORS, HardwareErrorCode } from '@onetokenfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import { UI_REQUEST } from '../constants/ui-request';
|
|
4
|
+
import { getPassphraseStateWithRefreshDeviceInfo } from '../utils/deviceFeaturesUtils';
|
|
5
|
+
import { BaseMethod } from './BaseMethod';
|
|
6
|
+
|
|
7
|
+
export default class GetPassphraseState extends BaseMethod {
|
|
8
|
+
init() {
|
|
9
|
+
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
|
|
10
|
+
this.useDevicePassphraseState = false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async run() {
|
|
14
|
+
if (!this.device.features)
|
|
15
|
+
return Promise.reject(ERRORS.TypedError(HardwareErrorCode.DeviceInitializeFailed));
|
|
16
|
+
|
|
17
|
+
const { passphraseState } = await getPassphraseStateWithRefreshDeviceInfo(this.device);
|
|
18
|
+
|
|
19
|
+
const { features } = this.device;
|
|
20
|
+
|
|
21
|
+
// refresh device info
|
|
22
|
+
if (features && features.passphrase_protection === true) {
|
|
23
|
+
return Promise.resolve(passphraseState);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return Promise.resolve(undefined);
|
|
27
|
+
}
|
|
28
|
+
}
|