From 11ddba5ab1470fb46a87ea9b702bf11f88763ecc Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Thu, 8 May 2025 13:14:23 +0200 Subject: [PATCH 06/17] add dummy device for ledger --- CMakeLists.txt | 6 +- external/randomx | 2 +- src/device/CMakeLists.txt | 6 +- src/device/device.cpp | 10 +- src/device/device.hpp | 12 +-- src/device/device_io_dummy.cpp | 161 ++++++++++++++++++++++++++++++ src/device/device_io_dummy.hpp | 82 +++++++++++++++ src/device/device_ledger.cpp | 6 +- src/device/device_ledger.hpp | 7 +- src/wallet/api/wallet.cpp | 100 +++++++++++++++++++ src/wallet/api/wallet.h | 14 +++ src/wallet/api/wallet2_api.h | 13 +++ src/wallet/api/wallet_manager.cpp | 12 ++- 13 files changed, 405 insertions(+), 26 deletions(-) create mode 100644 src/device/device_io_dummy.cpp create mode 100644 src/device/device_io_dummy.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c73b813d8..ce5ef4bab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -692,16 +692,21 @@ include_directories(${LMDB_INCLUDE}) include_directories(${LIBUNWIND_INCLUDE}) link_directories(${LIBUNWIND_LIBRARY_DIRS}) -# Final setup for hid -if (HIDAPI_FOUND) - message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}") - add_definitions(-DHAVE_HIDAPI) - include_directories(${HIDAPI_INCLUDE_DIR}) - link_directories(${LIBHIDAPI_LIBRARY_DIRS}) +if (HIDAPI_DUMMY) + add_definitions(-DHIDAPI_DUMMY) else() - message(STATUS "Could not find HIDAPI") + # Final setup for hid + if (HIDAPI_FOUND) + message(STATUS "Using HIDAPI include dir at ${HIDAPI_INCLUDE_DIR}") + add_definitions(-DHAVE_HIDAPI) + include_directories(${HIDAPI_INCLUDE_DIR}) + link_directories(${LIBHIDAPI_LIBRARY_DIRS}) + else() + message(STATUS "Could not find HIDAPI") + endif() endif() + # Trezor support check include(CheckTrezor) diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index e4f1159b5..14d398f87 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -29,10 +29,11 @@ set(device_sources device.cpp device_default.cpp + device_io_dummy.cpp log.cpp ) -if(HIDAPI_FOUND) +if(HIDAPI_FOUND OR HIDAPI_DUMMY) set(device_sources ${device_sources} device_ledger.cpp @@ -45,10 +46,11 @@ set(device_headers device_io.hpp device_default.hpp device_cold.hpp + device_io_dummy.hpp log.hpp ) -if(HIDAPI_FOUND) +if(HIDAPI_FOUND OR HIDAPI_DUMMY) set(device_headers ${device_headers} device_ledger.hpp diff --git a/src/device/device.cpp b/src/device/device.cpp index e6cd358b6..dd0701e0c 100644 --- a/src/device/device.cpp +++ b/src/device/device.cpp @@ -29,7 +29,7 @@ #include "device.hpp" #include "device_default.hpp" -#ifdef WITH_DEVICE_LEDGER +#if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY) #include "device_ledger.hpp" #endif #include "misc_log_ex.h" @@ -57,7 +57,7 @@ namespace hw { device_registry::device_registry(){ hw::core::register_all(registry); - #ifdef WITH_DEVICE_LEDGER + #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY) hw::ledger::register_all(registry); #endif atexit(clear_device_registry); @@ -83,11 +83,13 @@ namespace hw { auto device = registry.find(device_descriptor_lookup); if (device == registry.end()) { - MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: "); + std::stringstream ss("Device not found in registry: '" + device_descriptor + "'. Known devices: "); + MERROR("Device not found in registry: '" << device_descriptor << "'. Known devices: \n"); for( const auto& sm_pair : registry ) { + ss << "\n- " + sm_pair.first; MERROR(" - " << sm_pair.first); } - throw std::runtime_error("device not found: " + device_descriptor); + throw std::runtime_error("device not found: " + device_descriptor + "\n" + ss.str()); } return *device->second; } diff --git a/src/device/device.hpp b/src/device/device.hpp index 392703a24..ffd419779 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -34,17 +34,7 @@ #include "ringct/rctTypes.h" #include "cryptonote_config.h" - -#ifndef USE_DEVICE_LEDGER -#define USE_DEVICE_LEDGER 1 -#endif - -#if !defined(HAVE_HIDAPI) -#undef USE_DEVICE_LEDGER -#define USE_DEVICE_LEDGER 0 -#endif - -#if USE_DEVICE_LEDGER +#if defined(HAVE_HIDAPI) || defined(HIDAPI_DUMMY) #define WITH_DEVICE_LEDGER #endif diff --git a/src/device/device_io_dummy.cpp b/src/device/device_io_dummy.cpp new file mode 100644 index 000000000..01e6fc7b7 --- /dev/null +++ b/src/device/device_io_dummy.cpp @@ -0,0 +1,161 @@ +// Copyright (c) 2017-2022, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +// device_io_dummy +// Main goal of device_io_dummy is to emulate a hw::io::device_io without the need to actually +// connect a device. +// Many operating systems do not support giving raw USB access to a process (android), or don't +// support that at all (hi iOS), therefore other means of connection can be used, either USB +// abstraction provided by the OS (monerujo), or BLE (also monerujo). +// Monerujo implementation is written in Java, which makes it a nice fit for iOS, but makes the +// code extremely unportable, so for this reason the code in here is written in CPP. +// Data transport is made available in wallet2_api.h, so wallet developers can easily plug their +// own USB/BLE/other transport layer. + +#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) +#include +#include "log.hpp" +#include "device_io_dummy.hpp" +#include "device_ledger.hpp" + + +bool hw::io::device_io_dummy::stateIsConnected = false; +unsigned char* hw::io::device_io_dummy::sendToDevice = {}; +size_t hw::io::device_io_dummy::sendToDeviceLength = 0; +unsigned char* hw::io::device_io_dummy::receivedFromDevice = {}; +size_t hw::io::device_io_dummy::receivedFromDeviceLength = 0; +bool hw::io::device_io_dummy::waitsForDeviceSend = false; +bool hw::io::device_io_dummy::waitsForDeviceReceive = false; +void (*hw::io::device_io_dummy::sendToLedgerDeviceCallback)(unsigned char *command, unsigned int cmd_len) = nullptr; +std::mutex hw::io::device_io_dummy::mutex; +std::condition_variable hw::io::device_io_dummy::cv_send; +std::condition_variable hw::io::device_io_dummy::cv_receive; + +namespace hw { + namespace io { + +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "device.io_dummy" + device_io_dummy::device_io_dummy(int a, int b, int c, int d) { + MDEBUG("device_io_dummy(a: " << a << ", b: " << b << ", c: " << c << ", d: " << d <<")"); + } + + void device_io_dummy::init() { + MDEBUG("init()"); + } + + void device_io_dummy::connect(void *params) { + MDEBUG("connect(" << params << ")"); + stateIsConnected = true; + } + + void device_io_dummy::connect(const std::vector& known_devices) { + MDEBUG("connect(["); + for (const auto &item: known_devices) { + MDEBUG("{ interface_number: " << item.interface_number); + MDEBUG(" pid : " << item.pid); + MDEBUG(" usage_page : " << item.usage_page); + MDEBUG(" vid : " << item.vid << " },"); + } + MDEBUG("])"); + stateIsConnected = true; + } + + bool device_io_dummy::connected() const { + MDEBUG("connected()"); + return stateIsConnected; + } + + int device_io_dummy::exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input) { + MDEBUG("exchange(): locking mutex"); + std::unique_lock lock(mutex); + sendToDevice = command; + sendToDeviceLength = cmd_len; + waitsForDeviceSend = true; + waitsForDeviceReceive = true; + + // Call the callback if it's set + if (sendToLedgerDeviceCallback != nullptr) { + MDEBUG("exchange(): calling sendToLedgerDeviceCallback"); + sendToLedgerDeviceCallback(command, cmd_len); + } + MDEBUG("exchange(): waitsForDeviceSend"); + // Wait for the send flag to be cleared by external code + while (waitsForDeviceSend) { + cv_send.wait(lock); + MDEBUG("exchange(): waitsForDeviceSend notified"); + } + + MDEBUG("exchange(): waitsForDeviceReceive"); + // Wait for the receive flag to be cleared by external code + while (waitsForDeviceReceive) { + cv_receive.wait(lock); + MDEBUG("exchange(): waitsForDeviceReceive notified"); + } + + if (receivedFromDeviceLength > max_resp_len) { + MDEBUG("exchange(): receivedFromDeviceLength ("< lock(mutex); + + receivedFromDevice = static_cast(malloc(len)); + receivedFromDeviceLength = len; + memset(receivedFromDevice, 0, len); + memcpy(receivedFromDevice, data, len); + waitsForDeviceReceive = false; + waitsForDeviceSend = false; + cv_send.notify_all(); + cv_receive.notify_all(); + } + } +} +#endif // HAVE_HIDAPI \ No newline at end of file diff --git a/src/device/device_io_dummy.hpp b/src/device/device_io_dummy.hpp new file mode 100644 index 000000000..1128b9c1d --- /dev/null +++ b/src/device/device_io_dummy.hpp @@ -0,0 +1,82 @@ +// Copyright (c) 2017-2022, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +#ifdef HIDAPI_DUMMY + +#pragma once + +#include "device_io.hpp" +#include "device_io_hid.hpp" +#include +#include + +namespace hw { + namespace io { + struct hid_conn_params { + unsigned int vid; + unsigned int pid; + int interface_number; + unsigned short usage_page; + }; + class device_io_dummy : device_io { + private: + static std::mutex mutex; + + public: + static std::condition_variable cv_send; + static std::condition_variable cv_receive; + static bool stateIsConnected; + static unsigned char* sendToDevice; + static size_t sendToDeviceLength; + static unsigned char* receivedFromDevice; + static size_t receivedFromDeviceLength; + static bool waitsForDeviceSend; + static bool waitsForDeviceReceive; + static void (*sendToLedgerDeviceCallback)(unsigned char *command, unsigned int cmd_len); + + device_io_dummy() = default; + device_io_dummy(int a, int b, int c, int d); + ~device_io_dummy() = default; + + void init(); + void release(); + + void connect(void *parms); + void connect(const std::vector& known_devices); + void disconnect(); + bool connected() const; + + int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len, bool user_input); + + static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)); + static void setDeviceReceivedData(unsigned char* data, size_t len); + }; + }; +}; + +#endif // HAVE_HIDAPI diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index bb5b6f497..046201a1e 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -41,7 +41,7 @@ namespace hw { namespace ledger { - #ifdef WITH_DEVICE_LEDGER + #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY) #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "device.ledger" @@ -299,7 +299,7 @@ namespace hw { device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) { this->id = device_id++; - this->reset_buffer(); + this->reset_buffer(); this->mode = NONE; this->has_view_key = false; this->tx_in_progress = false; @@ -533,7 +533,9 @@ namespace hw { bool device_ledger::connect(void) { this->disconnect(); + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) hw_device.connect(known_devices); + #endif this->reset(); #ifdef DEBUG_HWDEVICE cryptonote::account_public_address pubkey; diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 03058c4f1..39454ca6d 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -35,6 +35,7 @@ #include "device.hpp" #include "log.hpp" #include "device_io_hid.hpp" +#include "device_io_dummy.hpp" #include #include @@ -56,7 +57,7 @@ namespace hw { void register_all(std::map> ®istry); - #ifdef WITH_DEVICE_LEDGER + #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY) // Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h #define SW_OK 0x9000 @@ -148,7 +149,11 @@ namespace hw { mutable boost::mutex command_locker; //IO +#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) + hw::io::device_io_dummy hw_device; +#else hw::io::device_io_hid hw_device; +#endif unsigned int length_send; unsigned char buffer_send[BUFFER_SEND_SIZE]; unsigned int length_recv; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 3fcd6f332..844a1c451 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -48,6 +48,9 @@ #include #include #include "bc-ur/src/bc-ur.hpp" +#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI) +#include "device/device_io_dummy.hpp" +#endif using namespace std; using namespace cryptonote; @@ -3178,4 +3181,101 @@ uint64_t WalletImpl::getBytesSent() return m_wallet->get_bytes_sent(); } + +// HIDAPI_DUMMY +bool Wallet::getStateIsConnected() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return false; + #else + return hw::io::device_io_dummy::stateIsConnected; + #endif +} + +unsigned char* Wallet::getSendToDevice() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return {}; + #else + return hw::io::device_io_dummy::sendToDevice; + #endif +} + +size_t Wallet::getSendToDeviceLength() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return -1; + #else + return hw::io::device_io_dummy::sendToDeviceLength; + #endif +} + +unsigned char* Wallet::getReceivedFromDevice() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return {}; + #else + return hw::io::device_io_dummy::receivedFromDevice; + #endif +} + +size_t Wallet::getReceivedFromDeviceLength() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return -1; + #else + return hw::io::device_io_dummy::receivedFromDeviceLength; + #endif +} + +bool Wallet::getWaitsForDeviceSend() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return false; + #else + return hw::io::device_io_dummy::waitsForDeviceSend; + #endif +} + +bool Wallet::getWaitsForDeviceReceive() { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return false; + #else + return hw::io::device_io_dummy::waitsForDeviceReceive; + #endif +} + +void Wallet::setDeviceReceivedData(unsigned char* data, size_t len) { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return; + #else + hw::io::device_io_dummy::setDeviceReceivedData(data, len); + #endif +} + +void Wallet::setDeviceSendData(unsigned char* data, size_t len) { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return; + #else + hw::io::device_io_dummy::sendToDevice = static_cast(malloc(len)); + hw::io::device_io_dummy::sendToDeviceLength = len; + memset(hw::io::device_io_dummy::sendToDevice, 0, len); + memcpy(hw::io::device_io_dummy::sendToDevice, data, len); + hw::io::device_io_dummy::waitsForDeviceSend = false; + hw::io::device_io_dummy::cv_send.notify_all(); + #endif +} + +void Wallet::setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)) { + #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)) + MERROR("MONERO compiled with #if !(defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI))"); + return; + #else + hw::io::device_io_dummy::setLedgerCallback(sendToLedgerDevice); + #endif +} + } // namespace diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index edf8bb8ce..6bfb61cb8 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -301,6 +301,20 @@ private: // cache connection status to avoid unnecessary RPC calls mutable std::atomic m_is_connected; boost::optional m_daemon_login{}; + + bool getStateIsConnected(); + + unsigned char *getSendToDevice(); + + size_t getSendToDeviceLength(); + + unsigned char *getReceivedFromDevice(); + + size_t getReceivedFromDeviceLength(); + + bool getWaitsForDeviceSend(); + + bool getWaitsForDeviceReceive(); }; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 764adbfbf..a48a6be54 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -1150,6 +1150,19 @@ struct Wallet //! get bytes sent virtual uint64_t getBytesSent() = 0; + + // HIDAPI_DUMMY + static bool getStateIsConnected(); + static unsigned char* getSendToDevice(); + static size_t getSendToDeviceLength(); + static unsigned char* getReceivedFromDevice(); + static size_t getReceivedFromDeviceLength(); + static bool getWaitsForDeviceSend(); + static bool getWaitsForDeviceReceive(); + + static void setDeviceReceivedData(unsigned char* data, size_t len); + static void setDeviceSendData(unsigned char* data, size_t len); + static void setLedgerCallback(void (*sendToLedgerDevice)(unsigned char *command, unsigned int cmd_len)); }; /** diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index e81b8f83a..277be6ac9 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -188,10 +188,14 @@ bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name, bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const { - hw::device::device_type type; - bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds); - device_type = static_cast(type); - return r; + try { + hw::device::device_type type; + bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds); + device_type = static_cast(type); + return r; + } catch (...) { + return false; + } } std::vector WalletManagerImpl::findWallets(const std::string &path) -- 2.49.0