mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-22 11:39:25 +00:00
Trezor support
This commit is contained in:
parent
531cc5f980
commit
062022f9d1
19 changed files with 156 additions and 23 deletions
|
@ -17,7 +17,7 @@ option(LOCALMONERO "Include LocalMonero module" ON)
|
||||||
option(XMRIG "Include XMRig module" ON)
|
option(XMRIG "Include XMRig module" ON)
|
||||||
option(TOR_BIN "Path to Tor binary to embed inside Feather" OFF)
|
option(TOR_BIN "Path to Tor binary to embed inside Feather" OFF)
|
||||||
option(CHECK_UPDATES "Enable checking for application updates" OFF)
|
option(CHECK_UPDATES "Enable checking for application updates" OFF)
|
||||||
option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
|
option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
||||||
option(DONATE_BEG "Prompt donation window every once in a while" ON)
|
option(DONATE_BEG "Prompt donation window every once in a while" ON)
|
||||||
option(WITH_SCANNER "Enable webcam QR scanner" OFF)
|
option(WITH_SCANNER "Enable webcam QR scanner" OFF)
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ if(DEBUG)
|
||||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(MONERO_HEAD "36fb05da3394505f8033ceb8806b28909617696f")
|
set(MONERO_HEAD "9e7caf0efe035da08293232a73b41021911d1b5f")
|
||||||
set(BUILD_GUI_DEPS ON)
|
set(BUILD_GUI_DEPS ON)
|
||||||
set(ARCH "x86-64")
|
set(ARCH "x86-64")
|
||||||
set(BUILD_64 ON)
|
set(BUILD_64 ON)
|
||||||
|
@ -73,6 +73,8 @@ add_subdirectory(monero)
|
||||||
set_property(TARGET wallet_merged PROPERTY FOLDER "monero")
|
set_property(TARGET wallet_merged PROPERTY FOLDER "monero")
|
||||||
get_directory_property(ARCH_WIDTH DIRECTORY "monero" DEFINITION ARCH_WIDTH)
|
get_directory_property(ARCH_WIDTH DIRECTORY "monero" DEFINITION ARCH_WIDTH)
|
||||||
get_directory_property(UNBOUND_LIBRARY DIRECTORY "monero" DEFINITION UNBOUND_LIBRARY)
|
get_directory_property(UNBOUND_LIBRARY DIRECTORY "monero" DEFINITION UNBOUND_LIBRARY)
|
||||||
|
get_directory_property(DEVICE_TREZOR_READY DIRECTORY "monero" DEFINITION DEVICE_TREZOR_READY)
|
||||||
|
get_directory_property(TREZOR_DEP_LIBS DIRECTORY "monero" DEFINITION TREZOR_DEP_LIBS)
|
||||||
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
include(VersionMonero)
|
include(VersionMonero)
|
||||||
|
|
|
@ -266,9 +266,11 @@ RUN git clone -b v4.1.1 --depth 1 https://github.com/fukuchi/libqrencode.git &&
|
||||||
|
|
||||||
# monero-seed: Required for Feather
|
# monero-seed: Required for Feather
|
||||||
# Tevador's 14 word seed library
|
# Tevador's 14 word seed library
|
||||||
|
ADD contrib/monero-seed.patch .
|
||||||
RUN git clone https://git.featherwallet.org/feather/monero-seed.git && \
|
RUN git clone https://git.featherwallet.org/feather/monero-seed.git && \
|
||||||
cd monero-seed && \
|
cd monero-seed && \
|
||||||
git reset --hard 4674ef09b6faa6fe602ab5ae0b9ca8e1fd7d5e1b && \
|
git reset --hard 4674ef09b6faa6fe602ab5ae0b9ca8e1fd7d5e1b && \
|
||||||
|
git apply /monero-seed.patch && \
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
|
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
|
||||||
make -Cbuild -j$THREADS && \
|
make -Cbuild -j$THREADS && \
|
||||||
make -Cbuild install && \
|
make -Cbuild install && \
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -39,7 +39,7 @@ CMAKEFLAGS = \
|
||||||
-DINSTALL_VENDORED_LIBUNBOUND=Off \
|
-DINSTALL_VENDORED_LIBUNBOUND=Off \
|
||||||
-DMANUAL_SUBMODULES=1 \
|
-DMANUAL_SUBMODULES=1 \
|
||||||
-DSTATIC=On \
|
-DSTATIC=On \
|
||||||
-DUSE_DEVICE_TREZOR=Off \
|
-DUSE_DEVICE_TREZOR=On \
|
||||||
$(CMAKEFLAGS_EXTRA)
|
$(CMAKEFLAGS_EXTRA)
|
||||||
|
|
||||||
release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64"
|
release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64"
|
||||||
|
|
|
@ -250,6 +250,10 @@ target_link_libraries(feather
|
||||||
${LIBZIP_LIBRARIES}
|
${LIBZIP_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(DEVICE_TREZOR_READY)
|
||||||
|
target_link_libraries(feather ${TREZOR_DEP_LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
if (WITH_SCANNER)
|
if (WITH_SCANNER)
|
||||||
target_link_libraries(feather
|
target_link_libraries(feather
|
||||||
Qt5::Multimedia
|
Qt5::Multimedia
|
||||||
|
|
|
@ -151,7 +151,7 @@ void MainWindow::initStatusBar() {
|
||||||
connect(m_statusBtnTor, &StatusBarButton::clicked, this, &MainWindow::menuTorClicked);
|
connect(m_statusBtnTor, &StatusBarButton::clicked, this, &MainWindow::menuTorClicked);
|
||||||
this->statusBar()->addPermanentWidget(m_statusBtnTor);
|
this->statusBar()->addPermanentWidget(m_statusBtnTor);
|
||||||
|
|
||||||
m_statusBtnHwDevice = new StatusBarButton(icons()->icon("ledger.png"), "Ledger", this);
|
m_statusBtnHwDevice = new StatusBarButton(this->hardwareDevicePairedIcon(), this->getHardwareDevice(), this);
|
||||||
connect(m_statusBtnHwDevice, &StatusBarButton::clicked, this, &MainWindow::menuHwDeviceClicked);
|
connect(m_statusBtnHwDevice, &StatusBarButton::clicked, this, &MainWindow::menuHwDeviceClicked);
|
||||||
this->statusBar()->addPermanentWidget(m_statusBtnHwDevice);
|
this->statusBar()->addPermanentWidget(m_statusBtnHwDevice);
|
||||||
m_statusBtnHwDevice->hide();
|
m_statusBtnHwDevice->hide();
|
||||||
|
@ -356,6 +356,8 @@ void MainWindow::initWalletContext() {
|
||||||
connect(m_ctx.get(), &AppContext::createTransactionSuccess, this, &MainWindow::onCreateTransactionSuccess);
|
connect(m_ctx.get(), &AppContext::createTransactionSuccess, this, &MainWindow::onCreateTransactionSuccess);
|
||||||
connect(m_ctx.get(), &AppContext::transactionCommitted, this, &MainWindow::onTransactionCommitted);
|
connect(m_ctx.get(), &AppContext::transactionCommitted, this, &MainWindow::onTransactionCommitted);
|
||||||
connect(m_ctx.get(), &AppContext::deviceError, this, &MainWindow::onDeviceError);
|
connect(m_ctx.get(), &AppContext::deviceError, this, &MainWindow::onDeviceError);
|
||||||
|
connect(m_ctx.get(), &AppContext::deviceButtonRequest, this, &MainWindow::onDeviceButtonRequest);
|
||||||
|
connect(m_ctx.get(), &AppContext::deviceButtonPressed, this, &MainWindow::onDeviceButtonPressed);
|
||||||
connect(m_ctx.get(), &AppContext::initiateTransaction, this, &MainWindow::onInitiateTransaction);
|
connect(m_ctx.get(), &AppContext::initiateTransaction, this, &MainWindow::onInitiateTransaction);
|
||||||
connect(m_ctx.get(), &AppContext::endTransaction, this, &MainWindow::onEndTransaction);
|
connect(m_ctx.get(), &AppContext::endTransaction, this, &MainWindow::onEndTransaction);
|
||||||
connect(m_ctx.get(), &AppContext::customRestoreHeightSet, this, &MainWindow::onCustomRestoreHeightSet);
|
connect(m_ctx.get(), &AppContext::customRestoreHeightSet, this, &MainWindow::onCustomRestoreHeightSet);
|
||||||
|
@ -801,6 +803,26 @@ void MainWindow::updateWidgetIcons() {
|
||||||
m_localMoneroWidget->skinChanged();
|
m_localMoneroWidget->skinChanged();
|
||||||
#endif
|
#endif
|
||||||
ui->conversionWidget->skinChanged();
|
ui->conversionWidget->skinChanged();
|
||||||
|
|
||||||
|
m_statusBtnHwDevice->setIcon(this->hardwareDevicePairedIcon());
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon MainWindow::hardwareDevicePairedIcon() {
|
||||||
|
QString filename;
|
||||||
|
if (m_ctx->wallet->isLedger())
|
||||||
|
filename = "ledger.png";
|
||||||
|
else if (m_ctx->wallet->isTrezor())
|
||||||
|
filename = ColorScheme::darkScheme ? "trezor_white.png" : "trezor.png";
|
||||||
|
return icons()->icon(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon MainWindow::hardwareDeviceUnpairedIcon() {
|
||||||
|
QString filename;
|
||||||
|
if (m_ctx->wallet->isLedger())
|
||||||
|
filename = "ledger_unpaired.png";
|
||||||
|
else if (m_ctx->wallet->isTrezor())
|
||||||
|
filename = ColorScheme::darkScheme ? "trezor_unpaired_white.png" : "trezor_unpaired.png";
|
||||||
|
return icons()->icon(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::closeEvent(QCloseEvent *event) {
|
void MainWindow::closeEvent(QCloseEvent *event) {
|
||||||
|
@ -1065,7 +1087,8 @@ void MainWindow::onDeviceError(const QString &error) {
|
||||||
if (m_showDeviceError) {
|
if (m_showDeviceError) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_statusBtnHwDevice->setIcon(icons()->icon("ledger_unpaired.png"));
|
|
||||||
|
m_statusBtnHwDevice->setIcon(this->hardwareDeviceUnpairedIcon());
|
||||||
while (true) {
|
while (true) {
|
||||||
m_showDeviceError = true;
|
m_showDeviceError = true;
|
||||||
auto result = QMessageBox::question(this, "Hardware device", "Lost connection to hardware device. Attempt to reconnect?");
|
auto result = QMessageBox::question(this, "Hardware device", "Lost connection to hardware device. Attempt to reconnect?");
|
||||||
|
@ -1080,11 +1103,38 @@ void MainWindow::onDeviceError(const QString &error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_statusBtnHwDevice->setIcon(icons()->icon("ledger.png"));
|
m_statusBtnHwDevice->setIcon(this->hardwareDevicePairedIcon());
|
||||||
m_ctx->wallet->startRefresh();
|
m_ctx->wallet->startRefresh();
|
||||||
m_showDeviceError = false;
|
m_showDeviceError = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onDeviceButtonRequest(quint64 code) {
|
||||||
|
if (m_ctx->wallet->isTrezor()) {
|
||||||
|
switch (code) {
|
||||||
|
case 8: // Confirm refresh: Do you really want to start refresh?
|
||||||
|
{
|
||||||
|
if (m_constructingTransaction) { // This code is also used when signing a tx...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_splashDialog->setMessage("Confirm refresh on device to proceed.");
|
||||||
|
m_splashDialog->setIcon(QPixmap(":/assets/images/confirmed.png"));
|
||||||
|
m_splashDialog->show();
|
||||||
|
m_splashDialog->setEnabled(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onDeviceButtonPressed() {
|
||||||
|
if (m_constructingTransaction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_splashDialog->hide();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::updateNetStats() {
|
void MainWindow::updateNetStats() {
|
||||||
if (m_ctx->wallet == nullptr) {
|
if (m_ctx->wallet == nullptr) {
|
||||||
m_statusLabelNetStats->setText("");
|
m_statusLabelNetStats->setText("");
|
||||||
|
|
|
@ -171,6 +171,8 @@ private slots:
|
||||||
void showRestoreHeightDialog();
|
void showRestoreHeightDialog();
|
||||||
void importTransaction();
|
void importTransaction();
|
||||||
void onDeviceError(const QString &error);
|
void onDeviceError(const QString &error);
|
||||||
|
void onDeviceButtonRequest(quint64 code);
|
||||||
|
void onDeviceButtonPressed();
|
||||||
void menuHwDeviceClicked();
|
void menuHwDeviceClicked();
|
||||||
void onUpdatesAvailable(const QJsonObject &updates);
|
void onUpdatesAvailable(const QJsonObject &updates);
|
||||||
void toggleSearchbar(bool enabled);
|
void toggleSearchbar(bool enabled);
|
||||||
|
@ -205,6 +207,9 @@ private:
|
||||||
void updateRecentlyOpened(const QString &filename);
|
void updateRecentlyOpened(const QString &filename);
|
||||||
void updateWidgetIcons();
|
void updateWidgetIcons();
|
||||||
|
|
||||||
|
QIcon hardwareDevicePairedIcon();
|
||||||
|
QIcon hardwareDeviceUnpairedIcon();
|
||||||
|
|
||||||
QScopedPointer<Ui::MainWindow> ui;
|
QScopedPointer<Ui::MainWindow> ui;
|
||||||
WindowManager *m_windowManager;
|
WindowManager *m_windowManager;
|
||||||
QSharedPointer<AppContext> m_ctx;
|
QSharedPointer<AppContext> m_ctx;
|
||||||
|
|
|
@ -228,7 +228,7 @@ void WindowManager::tryCreateWallet(FeatherSeed seed, const QString &path, const
|
||||||
this->onWalletOpened(wallet);
|
this->onWalletOpened(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::tryCreateWalletFromDevice(const QString &path, const QString &password, int restoreHeight)
|
void WindowManager::tryCreateWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight)
|
||||||
{
|
{
|
||||||
if (Utils::fileExists(path)) {
|
if (Utils::fileExists(path)) {
|
||||||
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
auto err = QString("Failed to write wallet to path: \"%1\"; file already exists.").arg(path);
|
||||||
|
@ -237,7 +237,7 @@ void WindowManager::tryCreateWalletFromDevice(const QString &path, const QString
|
||||||
}
|
}
|
||||||
|
|
||||||
m_openingWallet = true;
|
m_openingWallet = true;
|
||||||
m_walletManager->createWalletFromDeviceAsync(path, password, constants::networkType, "Ledger", restoreHeight);
|
m_walletManager->createWalletFromDeviceAsync(path, password, constants::networkType, deviceName, restoreHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::tryCreateWalletFromKeys(const QString &path, const QString &password, const QString &address,
|
void WindowManager::tryCreateWalletFromKeys(const QString &path, const QString &password, const QString &address,
|
||||||
|
@ -294,16 +294,36 @@ void WindowManager::handleWalletError(const QString &message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::displayWalletErrorMessage(const QString &message) {
|
void WindowManager::displayWalletErrorMessage(const QString &message) {
|
||||||
QString errMsg = message;
|
QString errMsg = QString("Error: %1").arg(message);
|
||||||
|
|
||||||
|
// Ledger
|
||||||
if (message.contains("No device found")) {
|
if (message.contains("No device found")) {
|
||||||
errMsg += "\n\nThis wallet is backed by a hardware device. Make sure the Monero app is opened on the device.\n"
|
errMsg += "\n\nThis wallet is backed by a Ledger hardware device. Make sure the Monero app is opened on the device.\n"
|
||||||
"You may need to restart Feather before the device can get detected.";
|
"You may need to restart Feather before the device can get detected.";
|
||||||
}
|
}
|
||||||
if (message.contains("Unable to open device")) {
|
if (message.contains("Unable to open device")) {
|
||||||
errMsg += "\n\nThe device might be in use by a different application.";
|
errMsg += "\n\nThe device might be in use by a different application.";
|
||||||
#if defined(Q_OS_LINUX)
|
#if defined(Q_OS_LINUX)
|
||||||
errMsg += "\n\nNote: On Linux you may need to follow the instructions in the link below before the device can be opened:\n"
|
errMsg += "\n\nNote: On Linux you may need to follow the instructions in the link below before the device can be opened:\n"
|
||||||
"<a>https://support.ledger.com/hc/en-us/articles/115005165269-Fix-connection-issues</a>";
|
"https://support.ledger.com/hc/en-us/articles/115005165269-Fix-connection-issues";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// TREZOR
|
||||||
|
if (message.contains("Unable to claim libusb device")) {
|
||||||
|
errMsg += "\n\nThis wallet is backed by a Trezor hardware device. Feather was unable to access the device. "
|
||||||
|
"Please make sure it is not opened by another program and try again.";
|
||||||
|
}
|
||||||
|
if (message.contains("Cannot get a device address")) {
|
||||||
|
errMsg += "\n\nRestart the Trezor hardware device and try again.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.contains("Could not connect to the device Trezor") || message.contains("Device connect failed")) {
|
||||||
|
errMsg += "\n\nThis wallet is backed by a Trezor hardware device. Make sure the device is connected to your computer and unlocked.\n"
|
||||||
|
"You may need to restart Feather before the device can be detected.";
|
||||||
|
#if defined(Q_OS_LINUX)
|
||||||
|
errMsg += "\n\nNote: On Linux you may need to follow the instructions in the link below before the device can be opened:\n"
|
||||||
|
"https://wiki.trezor.io/Udev_rules";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +350,19 @@ void WindowManager::displayWalletErrorMessage(const QString &message) {
|
||||||
// ######################## DEVICE ########################
|
// ######################## DEVICE ########################
|
||||||
|
|
||||||
void WindowManager::onDeviceButtonRequest(quint64 code) {
|
void WindowManager::onDeviceButtonRequest(quint64 code) {
|
||||||
m_splashDialog->setMessage("Action required on device: Export the view key to open the wallet.");
|
QString message;
|
||||||
|
switch (code) {
|
||||||
|
case 1: // Trezor
|
||||||
|
message = "Action required on device: enter your PIN to continue.";
|
||||||
|
break;
|
||||||
|
case 8: // Trezor
|
||||||
|
message = "Action required on device: Export watch-only credentials to open the wallet.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message = "Action required on device: Export the view key to open the wallet.";
|
||||||
|
}
|
||||||
|
|
||||||
|
m_splashDialog->setMessage(message);
|
||||||
m_splashDialog->setIcon(QPixmap(":/assets/images/key.png"));
|
m_splashDialog->setIcon(QPixmap(":/assets/images/key.png"));
|
||||||
m_splashDialog->show();
|
m_splashDialog->show();
|
||||||
m_splashDialog->setEnabled(true);
|
m_splashDialog->setEnabled(true);
|
||||||
|
|
|
@ -43,7 +43,7 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset);
|
void tryCreateWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset);
|
||||||
void tryCreateWalletFromDevice(const QString &path, const QString &password, int restoreHeight);
|
void tryCreateWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight);
|
||||||
void tryCreateWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
|
void tryCreateWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight);
|
||||||
|
|
||||||
bool autoOpenWallet();
|
bool autoOpenWallet();
|
||||||
|
|
|
@ -38,6 +38,7 @@ AppContext::AppContext(Wallet *wallet)
|
||||||
connect(this->wallet.get(), &Wallet::transactionCreated, this, &AppContext::onTransactionCreated);
|
connect(this->wallet.get(), &Wallet::transactionCreated, this, &AppContext::onTransactionCreated);
|
||||||
connect(this->wallet.get(), &Wallet::deviceError, this, &AppContext::onDeviceError);
|
connect(this->wallet.get(), &Wallet::deviceError, this, &AppContext::onDeviceError);
|
||||||
connect(this->wallet.get(), &Wallet::deviceButtonRequest, this, &AppContext::onDeviceButtonRequest);
|
connect(this->wallet.get(), &Wallet::deviceButtonRequest, this, &AppContext::onDeviceButtonRequest);
|
||||||
|
connect(this->wallet.get(), &Wallet::deviceButtonPressed, this, &AppContext::onDeviceButtonPressed);
|
||||||
connect(this->wallet.get(), &Wallet::connectionStatusChanged, [this]{
|
connect(this->wallet.get(), &Wallet::connectionStatusChanged, [this]{
|
||||||
this->nodes->autoConnect();
|
this->nodes->autoConnect();
|
||||||
});
|
});
|
||||||
|
@ -190,6 +191,10 @@ void AppContext::onDeviceButtonRequest(quint64 code) {
|
||||||
emit deviceButtonRequest(code);
|
emit deviceButtonRequest(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppContext::onDeviceButtonPressed() {
|
||||||
|
emit deviceButtonPressed();
|
||||||
|
}
|
||||||
|
|
||||||
void AppContext::onDeviceError(const QString &message) {
|
void AppContext::onDeviceError(const QString &message) {
|
||||||
qCritical() << "Device error: " << message;
|
qCritical() << "Device error: " << message;
|
||||||
emit deviceError(message);
|
emit deviceError(message);
|
||||||
|
|
|
@ -59,6 +59,7 @@ public slots:
|
||||||
void onAmountPrecisionChanged(int precision);
|
void onAmountPrecisionChanged(int precision);
|
||||||
void onMultiBroadcast(PendingTransaction *tx);
|
void onMultiBroadcast(PendingTransaction *tx);
|
||||||
void onDeviceButtonRequest(quint64 code);
|
void onDeviceButtonRequest(quint64 code);
|
||||||
|
void onDeviceButtonPressed();
|
||||||
void onDeviceError(const QString &message);
|
void onDeviceError(const QString &message);
|
||||||
|
|
||||||
void onTorSettingsChanged(); // should not be here
|
void onTorSettingsChanged(); // should not be here
|
||||||
|
@ -92,6 +93,7 @@ signals:
|
||||||
void initiateTransaction();
|
void initiateTransaction();
|
||||||
void endTransaction();
|
void endTransaction();
|
||||||
void deviceButtonRequest(quint64 code);
|
void deviceButtonRequest(quint64 code);
|
||||||
|
void deviceButtonPressed();
|
||||||
void deviceError(const QString &message);
|
void deviceError(const QString &message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -107,7 +107,9 @@
|
||||||
<file>assets/images/tor_logo_disabled.png</file>
|
<file>assets/images/tor_logo_disabled.png</file>
|
||||||
<file>assets/images/tor_logo.png</file>
|
<file>assets/images/tor_logo.png</file>
|
||||||
<file>assets/images/trezor.png</file>
|
<file>assets/images/trezor.png</file>
|
||||||
|
<file>assets/images/trezor_white.png</file>
|
||||||
<file>assets/images/trezor_unpaired.png</file>
|
<file>assets/images/trezor_unpaired.png</file>
|
||||||
|
<file>assets/images/trezor_unpaired_white.png</file>
|
||||||
<file>assets/images/unconfirmed.png</file>
|
<file>assets/images/unconfirmed.png</file>
|
||||||
<file>assets/images/unlock.png</file>
|
<file>assets/images/unlock.png</file>
|
||||||
<file>assets/images/unlock.svg</file>
|
<file>assets/images/unlock.svg</file>
|
||||||
|
|
BIN
src/assets/images/trezor_unpaired_white.png
Normal file
BIN
src/assets/images/trezor_unpaired_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/images/trezor_white.png
Normal file
BIN
src/assets/images/trezor_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
|
@ -26,6 +26,12 @@ SignVerifyDialog::SignVerifyDialog(Wallet *wallet, QWidget *parent)
|
||||||
ui->address->setText(m_wallet->address(0, 0));
|
ui->address->setText(m_wallet->address(0, 0));
|
||||||
ui->address->setCursorPosition(0);
|
ui->address->setCursorPosition(0);
|
||||||
|
|
||||||
|
if (m_wallet->isHwBacked()) {
|
||||||
|
// We don't have the secret spend key to sign messages
|
||||||
|
ui->btn_Sign->setEnabled(false);
|
||||||
|
ui->btn_Sign->setToolTip("Message signing is not supported on this hardware device.");
|
||||||
|
}
|
||||||
|
|
||||||
ui->btn_Copy->setVisible(false);
|
ui->btn_Copy->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,10 @@ PageHardwareDevice::PageHardwareDevice(WizardFields *fields, QWidget *parent)
|
||||||
, m_fields(fields)
|
, m_fields(fields)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->combo_deviceType->addItem("Ledger Nano S", DeviceType::LEDGER_NANO_S);
|
||||||
|
ui->combo_deviceType->addItem("Ledger Nano X", DeviceType::LEDGER_NANO_X);
|
||||||
|
ui->combo_deviceType->addItem("Trezor Model T", DeviceType::TREZOR_MODEL_T);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageHardwareDevice::initializePage() {
|
void PageHardwareDevice::initializePage() {
|
||||||
|
@ -28,6 +32,7 @@ int PageHardwareDevice::nextId() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PageHardwareDevice::validatePage() {
|
bool PageHardwareDevice::validatePage() {
|
||||||
|
m_fields->deviceType = static_cast<DeviceType>(ui->combo_deviceType->currentData().toInt());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,13 +22,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="comboBox">
|
<widget class="QComboBox" name="combo_deviceType"/>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ledger Nano S/X</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line">
|
<widget class="Line" name="line">
|
||||||
|
|
|
@ -98,7 +98,14 @@ QString PageWalletFile::defaultWalletName() {
|
||||||
do {
|
do {
|
||||||
QString walletStr = QString("wallet_%1");
|
QString walletStr = QString("wallet_%1");
|
||||||
if (m_fields->mode == WizardMode::CreateWalletFromDevice) {
|
if (m_fields->mode == WizardMode::CreateWalletFromDevice) {
|
||||||
walletStr = QString("ledger_%1");
|
switch (m_fields->deviceType) {
|
||||||
|
case DeviceType::LEDGER_NANO_S:
|
||||||
|
case DeviceType::LEDGER_NANO_X:
|
||||||
|
walletStr = QString("ledger_%1");
|
||||||
|
break;
|
||||||
|
case DeviceType::TREZOR_MODEL_T:
|
||||||
|
walletStr = QString("trezor_%1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
walletName = walletStr.arg(count);
|
walletName = walletStr.arg(count);
|
||||||
count++;
|
count++;
|
||||||
|
|
|
@ -93,7 +93,17 @@ void WalletWizard::onCreateWallet() {
|
||||||
restoreHeight = m_wizardFields.restoreHeight;
|
restoreHeight = m_wizardFields.restoreHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit createWalletFromDevice(walletPath, m_wizardFields.password, restoreHeight);
|
QString deviceName;
|
||||||
|
switch (m_wizardFields.deviceType) {
|
||||||
|
case DeviceType::LEDGER_NANO_S:
|
||||||
|
case DeviceType::LEDGER_NANO_X:
|
||||||
|
deviceName = "Ledger";
|
||||||
|
break;
|
||||||
|
case DeviceType::TREZOR_MODEL_T:
|
||||||
|
deviceName = "Trezor";
|
||||||
|
}
|
||||||
|
|
||||||
|
emit createWalletFromDevice(walletPath, m_wizardFields.password, deviceName, restoreHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,12 @@ enum WizardMode {
|
||||||
CreateWalletFromDevice
|
CreateWalletFromDevice
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DeviceType {
|
||||||
|
LEDGER_NANO_S = 0,
|
||||||
|
LEDGER_NANO_X,
|
||||||
|
TREZOR_MODEL_T
|
||||||
|
};
|
||||||
|
|
||||||
struct WizardFields {
|
struct WizardFields {
|
||||||
QString walletName;
|
QString walletName;
|
||||||
QString walletDir;
|
QString walletDir;
|
||||||
|
@ -34,6 +40,7 @@ struct WizardFields {
|
||||||
WizardMode mode;
|
WizardMode mode;
|
||||||
int restoreHeight = 0;
|
int restoreHeight = 0;
|
||||||
SeedType seedType;
|
SeedType seedType;
|
||||||
|
DeviceType deviceType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WalletWizard : public QWizard
|
class WalletWizard : public QWizard
|
||||||
|
@ -63,7 +70,7 @@ signals:
|
||||||
void openWallet(QString path, QString password);
|
void openWallet(QString path, QString password);
|
||||||
void defaultWalletDirChanged(QString walletDir);
|
void defaultWalletDirChanged(QString walletDir);
|
||||||
|
|
||||||
void createWalletFromDevice(const QString &path, const QString &password, int restoreHeight);
|
void createWalletFromDevice(const QString &path, const QString &password, const QString &deviceName, int restoreHeight);
|
||||||
void createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic = false);
|
void createWalletFromKeys(const QString &path, const QString &password, const QString &address, const QString &viewkey, const QString &spendkey, quint64 restoreHeight, bool deterministic = false);
|
||||||
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset = "");
|
void createWallet(FeatherSeed seed, const QString &path, const QString &password, const QString &seedOffset = "");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue