mirror of
https://github.com/monero-project/monero-gui
synced 2024-12-19 04:45:53 +01:00
trezor: support new passphrase entry mechanism
- passphrase can be prompted also when wallet is running (thus added to the wallet listener) - device/host decision is now made on the host
This commit is contained in:
parent
38612c1285
commit
86d21a34ba
104
components/DevicePassphraseDialog.qml
Normal file
104
components/DevicePassphraseDialog.qml
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright (c) 2014-2020, 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.
|
||||
|
||||
import QtQuick 2.9
|
||||
import "." as MoneroComponents
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var onAcceptedCallback
|
||||
property var onWalletEntryCallback
|
||||
property var onRejectedCallback
|
||||
|
||||
function open(canEnterOnDevice_) {
|
||||
var canEnterOnDevice = canEnterOnDevice_ !== null ? canEnterOnDevice_ : canEnterOnDevice
|
||||
root.visible = true;
|
||||
|
||||
if (canEnterOnDevice) {
|
||||
entryChooserDialog.okText = qsTr("Hardware wallet")
|
||||
entryChooserDialog.cancelText = qsTr("Computer")
|
||||
entryChooserDialog.open()
|
||||
} else {
|
||||
openPassphraseDialog()
|
||||
}
|
||||
}
|
||||
|
||||
function openPassphraseDialog() {
|
||||
root.visible = true
|
||||
passphraseDialog.openPassphraseDialog()
|
||||
}
|
||||
|
||||
function close() {
|
||||
root.visible = false;
|
||||
if (entryChooserDialog.visible)
|
||||
entryChooserDialog.close()
|
||||
if (passphraseDialog.visible)
|
||||
passphraseDialog.close()
|
||||
}
|
||||
|
||||
StandardDialog {
|
||||
id: entryChooserDialog
|
||||
title: qsTr("Hardware wallet passphrase") + translationManager.emptyString
|
||||
text: qsTr("Please select where you want to enter passphrase.\nIt is recommended to enter passphrase on the hardware wallet for better security.") + translationManager.emptyString
|
||||
|
||||
onAccepted: {
|
||||
if (onWalletEntryCallback){
|
||||
onWalletEntryCallback()
|
||||
}
|
||||
}
|
||||
|
||||
onRejected: {
|
||||
openPassphraseDialog()
|
||||
}
|
||||
|
||||
onCloseCallback: {
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
PasswordDialog {
|
||||
id: passphraseDialog
|
||||
anchors.fill: parent
|
||||
passphraseDialogMode: true
|
||||
|
||||
onAcceptedPassphrase: {
|
||||
if (onAcceptedCallback)
|
||||
onAcceptedCallback(passphraseDialog.password);
|
||||
}
|
||||
|
||||
onRejectedPassphrase: {
|
||||
if (onRejectedCallback)
|
||||
onRejectedCallback();
|
||||
}
|
||||
|
||||
onCloseCallback: {
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
48
main.qml
48
main.qml
@ -293,6 +293,7 @@ ApplicationWindow {
|
||||
currentWallet.connectionStatusChanged.disconnect(onWalletConnectionStatusChanged)
|
||||
currentWallet.deviceButtonRequest.disconnect(onDeviceButtonRequest);
|
||||
currentWallet.deviceButtonPressed.disconnect(onDeviceButtonPressed);
|
||||
currentWallet.walletPassphraseNeeded.disconnect(onWalletPassphraseNeededWallet);
|
||||
currentWallet.transactionCommitted.disconnect(onTransactionCommitted);
|
||||
middlePanel.paymentClicked.disconnect(handlePayment);
|
||||
middlePanel.sweepUnmixableClicked.disconnect(handleSweepUnmixable);
|
||||
@ -360,6 +361,7 @@ ApplicationWindow {
|
||||
currentWallet.connectionStatusChanged.connect(onWalletConnectionStatusChanged)
|
||||
currentWallet.deviceButtonRequest.connect(onDeviceButtonRequest);
|
||||
currentWallet.deviceButtonPressed.connect(onDeviceButtonPressed);
|
||||
currentWallet.walletPassphraseNeeded.connect(onWalletPassphraseNeededWallet);
|
||||
currentWallet.transactionCommitted.connect(onTransactionCommitted);
|
||||
middlePanel.paymentClicked.connect(handlePayment);
|
||||
middlePanel.sweepUnmixableClicked.connect(handleSweepUnmixable);
|
||||
@ -558,19 +560,32 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
function onWalletPassphraseNeeded(){
|
||||
function onWalletPassphraseNeededManager(on_device){
|
||||
onWalletPassphraseNeeded(walletManager, on_device)
|
||||
}
|
||||
|
||||
function onWalletPassphraseNeededWallet(on_device){
|
||||
onWalletPassphraseNeeded(currentWallet, on_device)
|
||||
}
|
||||
|
||||
function onWalletPassphraseNeeded(handler, on_device){
|
||||
hideProcessingSplash();
|
||||
|
||||
console.log(">>> wallet passphrase needed: ")
|
||||
passwordDialog.onAcceptedPassphraseCallback = function() {
|
||||
walletManager.onPassphraseEntered(passwordDialog.password);
|
||||
devicePassphraseDialog.onAcceptedCallback = function(passphrase) {
|
||||
handler.onPassphraseEntered(passphrase, false, false);
|
||||
appWindow.onWalletOpening();
|
||||
}
|
||||
passwordDialog.onRejectedPassphraseCallback = function() {
|
||||
walletManager.onPassphraseEntered("", true);
|
||||
devicePassphraseDialog.onWalletEntryCallback = function() {
|
||||
handler.onPassphraseEntered("", true, false);
|
||||
appWindow.onWalletOpening();
|
||||
}
|
||||
passwordDialog.openPassphraseDialog()
|
||||
devicePassphraseDialog.onRejectedCallback = function() {
|
||||
handler.onPassphraseEntered("", false, true);
|
||||
appWindow.onWalletOpening();
|
||||
}
|
||||
|
||||
devicePassphraseDialog.open(on_device)
|
||||
}
|
||||
|
||||
function onWalletUpdate() {
|
||||
@ -1295,7 +1310,7 @@ ApplicationWindow {
|
||||
walletManager.deviceButtonRequest.connect(onDeviceButtonRequest);
|
||||
walletManager.deviceButtonPressed.connect(onDeviceButtonPressed);
|
||||
walletManager.checkUpdatesComplete.connect(onWalletCheckUpdatesComplete);
|
||||
walletManager.walletPassphraseNeeded.connect(onWalletPassphraseNeeded);
|
||||
walletManager.walletPassphraseNeeded.connect(onWalletPassphraseNeededManager);
|
||||
IPC.uriHandler.connect(onUriHandler);
|
||||
|
||||
if(typeof daemonManager != "undefined") {
|
||||
@ -1512,8 +1527,6 @@ ApplicationWindow {
|
||||
anchors.fill: parent
|
||||
property var onAcceptedCallback
|
||||
property var onRejectedCallback
|
||||
property var onAcceptedPassphraseCallback
|
||||
property var onRejectedPassphraseCallback
|
||||
onAccepted: {
|
||||
if (onAcceptedCallback)
|
||||
onAcceptedCallback();
|
||||
@ -1537,14 +1550,13 @@ ApplicationWindow {
|
||||
informationPopup.open();
|
||||
}
|
||||
onRejectedNewPassword: {}
|
||||
onAcceptedPassphrase: {
|
||||
if (onAcceptedPassphraseCallback)
|
||||
onAcceptedPassphraseCallback();
|
||||
}
|
||||
onRejectedPassphrase: {
|
||||
if (onRejectedPassphraseCallback)
|
||||
onRejectedPassphraseCallback();
|
||||
}
|
||||
}
|
||||
|
||||
DevicePassphraseDialog {
|
||||
id: devicePassphraseDialog
|
||||
visible: false
|
||||
z: parent.z + 1
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
InputDialog {
|
||||
@ -1708,7 +1720,7 @@ ApplicationWindow {
|
||||
anchors.fill: blurredArea
|
||||
source: blurredArea
|
||||
radius: 64
|
||||
visible: passwordDialog.visible || inputDialog.visible || splash.visible || updateDialog.visible
|
||||
visible: passwordDialog.visible || inputDialog.visible || splash.visible || updateDialog.visible || devicePassphraseDialog.visible
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,6 +53,7 @@ HEADERS += \
|
||||
src/main/oscursor.h \
|
||||
src/libwalletqt/WalletManager.h \
|
||||
src/libwalletqt/Wallet.h \
|
||||
src/libwalletqt/PassphraseHelper.h \
|
||||
src/libwalletqt/PendingTransaction.h \
|
||||
src/libwalletqt/TransactionHistory.h \
|
||||
src/libwalletqt/TransactionInfo.h \
|
||||
@ -91,7 +92,9 @@ SOURCES += src/main/main.cpp \
|
||||
src/main/clipboardAdapter.cpp \
|
||||
src/main/oscursor.cpp \
|
||||
src/libwalletqt/WalletManager.cpp \
|
||||
src/libwalletqt/WalletListenerImpl.cpp \
|
||||
src/libwalletqt/Wallet.cpp \
|
||||
src/libwalletqt/PassphraseHelper.cpp \
|
||||
src/libwalletqt/PendingTransaction.cpp \
|
||||
src/libwalletqt/TransactionHistory.cpp \
|
||||
src/libwalletqt/TransactionInfo.cpp \
|
||||
|
1
qml.qrc
1
qml.qrc
@ -99,6 +99,7 @@
|
||||
<file>components/ProcessingSplash.qml</file>
|
||||
<file>components/ProgressBar.qml</file>
|
||||
<file>components/StandardDialog.qml</file>
|
||||
<file>components/DevicePassphraseDialog.qml</file>
|
||||
<file>pages/Sign.qml</file>
|
||||
<file>components/DaemonManagerDialog.qml</file>
|
||||
<file>version.js</file>
|
||||
|
@ -15,7 +15,9 @@ file(GLOB SOURCE_FILES
|
||||
"main/*.h"
|
||||
"main/*.cpp"
|
||||
"libwalletqt/WalletManager.cpp"
|
||||
"libwalletqt/WalletListenerImpl.cpp"
|
||||
"libwalletqt/Wallet.cpp"
|
||||
"libwalletqt/PassphraseHelper.cpp"
|
||||
"libwalletqt/PendingTransaction.cpp"
|
||||
"libwalletqt/TransactionHistory.cpp"
|
||||
"libwalletqt/TransactionInfo.cpp"
|
||||
@ -29,6 +31,7 @@ file(GLOB SOURCE_FILES
|
||||
"libwalletqt/UnsignedTransaction.cpp"
|
||||
"libwalletqt/WalletManager.h"
|
||||
"libwalletqt/Wallet.h"
|
||||
"libwalletqt/PassphraseHelper.h"
|
||||
"libwalletqt/PendingTransaction.h"
|
||||
"libwalletqt/TransactionHistory.h"
|
||||
"libwalletqt/TransactionInfo.h"
|
||||
|
70
src/libwalletqt/PassphraseHelper.cpp
Normal file
70
src/libwalletqt/PassphraseHelper.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2014-2020, 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.
|
||||
|
||||
#include "PassphraseHelper.h"
|
||||
#include <QMutexLocker>
|
||||
#include <QDebug>
|
||||
|
||||
Monero::optional<std::string> PassphraseHelper::onDevicePassphraseRequest(bool & on_device)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
QMutexLocker locker(&m_mutex_pass);
|
||||
m_passphrase_on_device = true;
|
||||
m_passphrase_abort = false;
|
||||
|
||||
if (m_prompter != nullptr){
|
||||
m_prompter->onWalletPassphraseNeeded(on_device);
|
||||
}
|
||||
|
||||
m_cond_pass.wait(&m_mutex_pass);
|
||||
|
||||
if (m_passphrase_abort)
|
||||
{
|
||||
throw std::runtime_error("Passphrase entry abort");
|
||||
}
|
||||
|
||||
on_device = m_passphrase_on_device;
|
||||
if (!on_device) {
|
||||
auto tmpPass = m_passphrase.toStdString();
|
||||
m_passphrase = QString();
|
||||
return Monero::optional<std::string>(tmpPass);
|
||||
} else {
|
||||
return Monero::optional<std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
void PassphraseHelper::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
QMutexLocker locker(&m_mutex_pass);
|
||||
m_passphrase = passphrase;
|
||||
m_passphrase_abort = entry_abort;
|
||||
m_passphrase_on_device = enter_on_device;
|
||||
|
||||
m_cond_pass.wakeAll();
|
||||
}
|
74
src/libwalletqt/PassphraseHelper.h
Normal file
74
src/libwalletqt/PassphraseHelper.h
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (c) 2014-2020, 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.
|
||||
|
||||
#ifndef MONERO_GUI_PASSPHRASEHELPER_H
|
||||
#define MONERO_GUI_PASSPHRASEHELPER_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <wallet/api/wallet2_api.h>
|
||||
#include <QMutex>
|
||||
#include <QPointer>
|
||||
#include <QWaitCondition>
|
||||
#include <QMutex>
|
||||
|
||||
/**
|
||||
* Implements component responsible for showing entry prompt to the user,
|
||||
* typically Wallet / Wallet manager.
|
||||
*/
|
||||
class PassprasePrompter {
|
||||
public:
|
||||
virtual void onWalletPassphraseNeeded(bool onDevice) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements receiver of the passphrase responsible for passing it back to the wallet,
|
||||
* typically wallet listener.
|
||||
*/
|
||||
class PassphraseReceiver {
|
||||
public:
|
||||
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) = 0;
|
||||
};
|
||||
|
||||
class PassphraseHelper {
|
||||
public:
|
||||
PassphraseHelper(PassprasePrompter * prompter=nullptr): m_prompter(prompter) {};
|
||||
PassphraseHelper(const PassphraseHelper & h): PassphraseHelper(h.m_prompter) {};
|
||||
Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device);
|
||||
void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort);
|
||||
|
||||
private:
|
||||
PassprasePrompter * m_prompter;
|
||||
QWaitCondition m_cond_pass;
|
||||
QMutex m_mutex_pass;
|
||||
QString m_passphrase;
|
||||
bool m_passphrase_abort;
|
||||
bool m_passphrase_on_device;
|
||||
|
||||
};
|
||||
|
||||
#endif //MONERO_GUI_PASSPHRASEHELPER_H
|
@ -58,66 +58,6 @@ namespace {
|
||||
static constexpr char ATTRIBUTE_SUBADDRESS_ACCOUNT[] ="gui.subaddress_account";
|
||||
}
|
||||
|
||||
class WalletListenerImpl : public Monero::WalletListener
|
||||
{
|
||||
public:
|
||||
WalletListenerImpl(Wallet * w)
|
||||
: m_wallet(w)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void moneySpent(const std::string &txId, uint64_t amount) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneySpent(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
|
||||
virtual void moneyReceived(const std::string &txId, uint64_t amount) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->unconfirmedMoneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
virtual void newBlock(uint64_t height) override
|
||||
{
|
||||
// qDebug() << __FUNCTION__;
|
||||
emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
|
||||
}
|
||||
|
||||
virtual void updated() override
|
||||
{
|
||||
emit m_wallet->updated();
|
||||
}
|
||||
|
||||
// called when wallet refreshed by background thread or explicitly
|
||||
virtual void refreshed() override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->refreshed();
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonRequest(uint64_t code) override
|
||||
{
|
||||
emit m_wallet->deviceButtonRequest(code);
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonPressed() override
|
||||
{
|
||||
emit m_wallet->deviceButtonPressed();
|
||||
}
|
||||
|
||||
private:
|
||||
Wallet * m_wallet;
|
||||
};
|
||||
|
||||
Wallet::Wallet(QObject * parent)
|
||||
: Wallet(nullptr, parent)
|
||||
{
|
||||
@ -1021,6 +961,19 @@ void Wallet::keyReuseMitigation2(bool mitigation)
|
||||
m_walletImpl->keyReuseMitigation2(mitigation);
|
||||
}
|
||||
|
||||
void Wallet::onWalletPassphraseNeeded(bool on_device)
|
||||
{
|
||||
emit this->walletPassphraseNeeded(on_device);
|
||||
}
|
||||
|
||||
void Wallet::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
if (m_walletListener != nullptr)
|
||||
{
|
||||
m_walletListener->onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
}
|
||||
|
||||
Wallet::Wallet(Monero::Wallet *w, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_walletImpl(w)
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "PendingTransaction.h" // we need to have an access to the PendingTransaction::Priority enum here;
|
||||
#include "UnsignedTransaction.h"
|
||||
#include "NetworkType.h"
|
||||
#include "PassphraseHelper.h"
|
||||
#include "WalletListenerImpl.h"
|
||||
|
||||
namespace Monero {
|
||||
struct Wallet; // forward declaration
|
||||
@ -57,7 +59,7 @@ class SubaddressModel;
|
||||
class SubaddressAccount;
|
||||
class SubaddressAccountModel;
|
||||
|
||||
class Wallet : public QObject
|
||||
class Wallet : public QObject, public PassprasePrompter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool disconnected READ disconnected NOTIFY disconnectedChanged)
|
||||
@ -348,6 +350,10 @@ public:
|
||||
Q_INVOKABLE void segregationHeight(quint64 height);
|
||||
Q_INVOKABLE void keyReuseMitigation2(bool mitigation);
|
||||
|
||||
// Passphrase entry for hardware wallets
|
||||
Q_INVOKABLE void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort=false);
|
||||
virtual void onWalletPassphraseNeeded(bool on_device) override;
|
||||
|
||||
// TODO: setListenter() when it implemented in API
|
||||
signals:
|
||||
// emitted on every event happened with wallet
|
||||
@ -367,6 +373,7 @@ signals:
|
||||
void walletCreationHeightChanged();
|
||||
void deviceButtonRequest(quint64 buttonCode);
|
||||
void deviceButtonPressed();
|
||||
void walletPassphraseNeeded(bool onDevice);
|
||||
void transactionCommitted(bool status, PendingTransaction *t, const QStringList& txid);
|
||||
void heightRefreshed(quint64 walletHeight, quint64 daemonHeight, quint64 targetHeight) const;
|
||||
void deviceShowAddressShowed();
|
||||
@ -432,7 +439,7 @@ private:
|
||||
bool m_connectionStatusRunning;
|
||||
QString m_daemonUsername;
|
||||
QString m_daemonPassword;
|
||||
Monero::WalletListener *m_walletListener;
|
||||
WalletListenerImpl *m_walletListener;
|
||||
FutureScheduler m_scheduler;
|
||||
QMutex m_storeMutex;
|
||||
};
|
||||
|
97
src/libwalletqt/WalletListenerImpl.cpp
Normal file
97
src/libwalletqt/WalletListenerImpl.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright (c) 2014-2020, 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.
|
||||
|
||||
#include "WalletListenerImpl.h"
|
||||
#include "Wallet.h"
|
||||
|
||||
WalletListenerImpl::WalletListenerImpl(Wallet * w)
|
||||
: m_wallet(w)
|
||||
, m_phelper(w)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void WalletListenerImpl::moneySpent(const std::string &txId, uint64_t amount)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneySpent(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::moneyReceived(const std::string &txId, uint64_t amount)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->moneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::unconfirmedMoneyReceived(const std::string &txId, uint64_t amount)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->unconfirmedMoneyReceived(QString::fromStdString(txId), amount);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::newBlock(uint64_t height)
|
||||
{
|
||||
// qDebug() << __FUNCTION__;
|
||||
emit m_wallet->newBlock(height, m_wallet->daemonBlockChainTargetHeight());
|
||||
}
|
||||
|
||||
void WalletListenerImpl::updated()
|
||||
{
|
||||
emit m_wallet->updated();
|
||||
}
|
||||
|
||||
// called when wallet refreshed by background thread or explicitly
|
||||
void WalletListenerImpl::refreshed()
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->refreshed();
|
||||
}
|
||||
|
||||
void WalletListenerImpl::onDeviceButtonRequest(uint64_t code)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->deviceButtonRequest(code);
|
||||
}
|
||||
|
||||
void WalletListenerImpl::onDeviceButtonPressed()
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_wallet->deviceButtonPressed();
|
||||
}
|
||||
|
||||
void WalletListenerImpl::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
m_phelper.onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
|
||||
Monero::optional<std::string> WalletListenerImpl::onDevicePassphraseRequest(bool & on_device)
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
return m_phelper.onDevicePassphraseRequest(on_device);
|
||||
}
|
68
src/libwalletqt/WalletListenerImpl.h
Normal file
68
src/libwalletqt/WalletListenerImpl.h
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2014-2020, 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.
|
||||
|
||||
#ifndef MONERO_GUI_WALLETLISTENERIMPL_H
|
||||
#define MONERO_GUI_WALLETLISTENERIMPL_H
|
||||
|
||||
#include "wallet/api/wallet2_api.h"
|
||||
#include "PassphraseHelper.h"
|
||||
|
||||
class Wallet;
|
||||
|
||||
class WalletListenerImpl : public Monero::WalletListener, public PassphraseReceiver
|
||||
{
|
||||
public:
|
||||
WalletListenerImpl(Wallet * w);
|
||||
|
||||
virtual void moneySpent(const std::string &txId, uint64_t amount) override;
|
||||
|
||||
virtual void moneyReceived(const std::string &txId, uint64_t amount) override;
|
||||
|
||||
virtual void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override;
|
||||
|
||||
virtual void newBlock(uint64_t height) override;
|
||||
|
||||
virtual void updated() override;
|
||||
|
||||
// called when wallet refreshed by background thread or explicitly
|
||||
virtual void refreshed() override;
|
||||
|
||||
virtual void onDeviceButtonRequest(uint64_t code) override;
|
||||
|
||||
virtual void onDeviceButtonPressed() override;
|
||||
|
||||
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) override;
|
||||
|
||||
virtual Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device) override;
|
||||
|
||||
private:
|
||||
Wallet * m_wallet;
|
||||
PassphraseHelper m_phelper;
|
||||
};
|
||||
|
||||
#endif //MONERO_GUI_WALLETLISTENERIMPL_H
|
@ -42,11 +42,12 @@
|
||||
#include <QString>
|
||||
|
||||
#include "qt/updater.h"
|
||||
#include "qt/ScopeGuard.h"
|
||||
|
||||
class WalletPassphraseListenerImpl : public Monero::WalletListener
|
||||
class WalletPassphraseListenerImpl : public Monero::WalletListener, public PassphraseReceiver
|
||||
{
|
||||
public:
|
||||
WalletPassphraseListenerImpl(WalletManager * mgr): m_mgr(mgr), m_wallet(nullptr) {}
|
||||
WalletPassphraseListenerImpl(WalletManager * mgr): m_mgr(mgr), m_phelper(mgr) {}
|
||||
|
||||
virtual void moneySpent(const std::string &txId, uint64_t amount) override { (void)txId; (void)amount; };
|
||||
virtual void moneyReceived(const std::string &txId, uint64_t amount) override { (void)txId; (void)amount; };
|
||||
@ -55,43 +56,33 @@ public:
|
||||
virtual void updated() override {};
|
||||
virtual void refreshed() override {};
|
||||
|
||||
virtual Monero::optional<std::string> onDevicePassphraseRequest(bool on_device) override
|
||||
virtual void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
if (on_device) return Monero::optional<std::string>();
|
||||
m_phelper.onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
|
||||
m_mgr->onWalletPassphraseNeeded(m_wallet);
|
||||
|
||||
if (m_mgr->m_passphrase_abort)
|
||||
{
|
||||
throw std::runtime_error("Passphrase entry abort");
|
||||
}
|
||||
|
||||
auto tmpPass = m_mgr->m_passphrase.toStdString();
|
||||
m_mgr->m_passphrase = QString();
|
||||
|
||||
return Monero::optional<std::string>(tmpPass);
|
||||
virtual Monero::optional<std::string> onDevicePassphraseRequest(bool & on_device) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
return m_phelper.onDevicePassphraseRequest(on_device);
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonRequest(uint64_t code) override
|
||||
{
|
||||
emit m_mgr->deviceButtonRequest(code);
|
||||
qDebug() << __FUNCTION__;
|
||||
emit m_mgr->deviceButtonRequest(code);
|
||||
}
|
||||
|
||||
virtual void onDeviceButtonPressed() override
|
||||
{
|
||||
emit m_mgr->deviceButtonPressed();
|
||||
}
|
||||
|
||||
virtual void onSetWallet(Monero::Wallet * wallet) override
|
||||
{
|
||||
qDebug() << __FUNCTION__;
|
||||
m_wallet = wallet;
|
||||
emit m_mgr->deviceButtonPressed();
|
||||
}
|
||||
|
||||
private:
|
||||
WalletManager * m_mgr;
|
||||
Monero::Wallet * m_wallet;
|
||||
PassphraseHelper m_phelper;
|
||||
};
|
||||
|
||||
WalletManager * WalletManager::m_instance = nullptr;
|
||||
@ -123,6 +114,13 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password,
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
WalletPassphraseListenerImpl tmpListener(this);
|
||||
m_mutex_passphraseReceiver.lock();
|
||||
m_passphraseReceiver = &tmpListener;
|
||||
m_mutex_passphraseReceiver.unlock();
|
||||
const auto cleanup = sg::make_scope_guard([this]() noexcept {
|
||||
QMutexLocker passphrase_locker(&m_mutex_passphraseReceiver);
|
||||
this->m_passphraseReceiver = nullptr;
|
||||
});
|
||||
|
||||
if (m_currentWallet) {
|
||||
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
|
||||
@ -186,6 +184,13 @@ Wallet *WalletManager::createWalletFromDevice(const QString &path, const QString
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
WalletPassphraseListenerImpl tmpListener(this);
|
||||
m_mutex_passphraseReceiver.lock();
|
||||
m_passphraseReceiver = &tmpListener;
|
||||
m_mutex_passphraseReceiver.unlock();
|
||||
const auto cleanup = sg::make_scope_guard([this]() noexcept {
|
||||
QMutexLocker passphrase_locker(&m_mutex_passphraseReceiver);
|
||||
this->m_passphraseReceiver = nullptr;
|
||||
});
|
||||
|
||||
if (m_currentWallet) {
|
||||
qDebug() << "Closing open m_currentWallet" << m_currentWallet;
|
||||
@ -529,6 +534,7 @@ bool WalletManager::clearWalletCache(const QString &wallet_path) const
|
||||
|
||||
WalletManager::WalletManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_passphraseReceiver(nullptr)
|
||||
, m_scheduler(this)
|
||||
{
|
||||
m_pimpl = Monero::WalletManagerFactory::getWalletManager();
|
||||
@ -539,22 +545,16 @@ WalletManager::~WalletManager()
|
||||
m_scheduler.shutdownWaitForFinished();
|
||||
}
|
||||
|
||||
void WalletManager::onWalletPassphraseNeeded(Monero::Wallet *)
|
||||
void WalletManager::onWalletPassphraseNeeded(bool on_device)
|
||||
{
|
||||
m_mutex_pass.lock();
|
||||
m_passphrase_abort = false;
|
||||
emit this->walletPassphraseNeeded();
|
||||
|
||||
m_cond_pass.wait(&m_mutex_pass);
|
||||
m_mutex_pass.unlock();
|
||||
emit this->walletPassphraseNeeded(on_device);
|
||||
}
|
||||
|
||||
void WalletManager::onPassphraseEntered(const QString &passphrase, bool entry_abort)
|
||||
void WalletManager::onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort)
|
||||
{
|
||||
m_mutex_pass.lock();
|
||||
m_passphrase = passphrase;
|
||||
m_passphrase_abort = entry_abort;
|
||||
|
||||
m_cond_pass.wakeAll();
|
||||
m_mutex_pass.unlock();
|
||||
QMutexLocker locker(&m_mutex_passphraseReceiver);
|
||||
if (m_passphraseReceiver != nullptr)
|
||||
{
|
||||
m_passphraseReceiver->onPassphraseEntered(passphrase, enter_on_device, entry_abort);
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,14 @@
|
||||
#include <QWaitCondition>
|
||||
#include "qt/FutureScheduler.h"
|
||||
#include "NetworkType.h"
|
||||
#include "PassphraseHelper.h"
|
||||
|
||||
class Wallet;
|
||||
namespace Monero {
|
||||
struct WalletManager;
|
||||
}
|
||||
|
||||
class WalletManager : public QObject
|
||||
class WalletManager : public QObject, public PassprasePrompter
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool connected READ connected)
|
||||
@ -185,14 +186,14 @@ public:
|
||||
// clear/rename wallet cache
|
||||
Q_INVOKABLE bool clearWalletCache(const QString &fileName) const;
|
||||
|
||||
Q_INVOKABLE void onWalletPassphraseNeeded(Monero::Wallet * wallet);
|
||||
Q_INVOKABLE void onPassphraseEntered(const QString &passphrase, bool entry_abort=false);
|
||||
Q_INVOKABLE void onPassphraseEntered(const QString &passphrase, bool enter_on_device, bool entry_abort=false);
|
||||
virtual void onWalletPassphraseNeeded(bool on_device) override;
|
||||
|
||||
signals:
|
||||
|
||||
void walletOpened(Wallet * wallet);
|
||||
void walletCreated(Wallet * wallet);
|
||||
void walletPassphraseNeeded();
|
||||
void walletPassphraseNeeded(bool onDevice);
|
||||
void deviceButtonRequest(quint64 buttonCode);
|
||||
void deviceButtonPressed();
|
||||
void checkUpdatesComplete(
|
||||
@ -216,12 +217,8 @@ private:
|
||||
Monero::WalletManager * m_pimpl;
|
||||
mutable QMutex m_mutex;
|
||||
QPointer<Wallet> m_currentWallet;
|
||||
|
||||
QWaitCondition m_cond_pass;
|
||||
QMutex m_mutex_pass;
|
||||
QString m_passphrase;
|
||||
bool m_passphrase_abort;
|
||||
|
||||
PassphraseReceiver * m_passphraseReceiver;
|
||||
QMutex m_mutex_passphraseReceiver;
|
||||
FutureScheduler m_scheduler;
|
||||
};
|
||||
|
||||
|
205
src/qt/ScopeGuard.h
Normal file
205
src/qt/ScopeGuard.h
Normal file
@ -0,0 +1,205 @@
|
||||
// Author: ricab
|
||||
// Source: https://github.com/ricab/scope_guard
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
//
|
||||
// Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
// distribute this software, either in source code form or as a compiled
|
||||
// binary, for any purpose, commercial or non-commercial, and by any
|
||||
// means.
|
||||
//
|
||||
// In jurisdictions that recognize copyright laws, the author or authors
|
||||
// of this software dedicate any and all copyright interest in the
|
||||
// software to the public domain. We make this dedication for the benefit
|
||||
// of the public at large and to the detriment of our heirs and
|
||||
// successors. We intend this dedication to be an overt act of
|
||||
// relinquishment in perpetuity of all present and future rights to this
|
||||
// software under copyright law.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// For more information, please refer to <http://unlicense.org>
|
||||
|
||||
#ifndef SCOPE_GUARD_HPP_
|
||||
#define SCOPE_GUARD_HPP_
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#if __cplusplus >= 201703L && defined(SG_REQUIRE_NOEXCEPT_IN_CPP17)
|
||||
#define SG_REQUIRE_NOEXCEPT
|
||||
#endif
|
||||
|
||||
namespace sg
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
/* --- Some custom type traits --- */
|
||||
|
||||
// Type trait determining whether a type is callable with no arguments
|
||||
template<typename T, typename = void>
|
||||
struct is_noarg_callable_t
|
||||
: public std::false_type
|
||||
{}; // in general, false
|
||||
|
||||
template<typename T>
|
||||
struct is_noarg_callable_t<T, decltype(std::declval<T&&>()())>
|
||||
: public std::true_type
|
||||
{}; // only true when call expression valid
|
||||
|
||||
// Type trait determining whether a no-argument callable returns void
|
||||
template<typename T>
|
||||
struct returns_void_t
|
||||
: public std::is_same<void, decltype(std::declval<T&&>()())>
|
||||
{};
|
||||
|
||||
/* Type trait determining whether a no-arg callable is nothrow invocable if
|
||||
required. This is where SG_REQUIRE_NOEXCEPT logic is encapsulated. */
|
||||
template<typename T>
|
||||
struct is_nothrow_invocable_if_required_t
|
||||
: public
|
||||
#ifdef SG_REQUIRE_NOEXCEPT
|
||||
std::is_nothrow_invocable<T> /* Note: _r variants not enough to
|
||||
confirm void return: any return can be
|
||||
discarded so all returns are
|
||||
compatible with void */
|
||||
#else
|
||||
std::true_type
|
||||
#endif
|
||||
{};
|
||||
|
||||
// logic AND of two or more type traits
|
||||
template<typename A, typename B, typename... C>
|
||||
struct and_t : public and_t<A, and_t<B, C...>>
|
||||
{}; // for more than two arguments
|
||||
|
||||
template<typename A, typename B>
|
||||
struct and_t<A, B> : public std::conditional<A::value, B, A>::type
|
||||
{}; // for two arguments
|
||||
|
||||
// Type trait determining whether a type is a proper scope_guard callback.
|
||||
template<typename T>
|
||||
struct is_proper_sg_callback_t
|
||||
: public and_t<is_noarg_callable_t<T>,
|
||||
returns_void_t<T>,
|
||||
is_nothrow_invocable_if_required_t<T>,
|
||||
std::is_nothrow_destructible<T>>
|
||||
{};
|
||||
|
||||
|
||||
/* --- The actual scope_guard template --- */
|
||||
|
||||
template<typename Callback,
|
||||
typename = typename std::enable_if<
|
||||
is_proper_sg_callback_t<Callback>::value>::type>
|
||||
class scope_guard;
|
||||
|
||||
|
||||
/* --- Now the friend maker --- */
|
||||
|
||||
template<typename Callback>
|
||||
detail::scope_guard<Callback> make_scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value); /*
|
||||
we need this in the inner namespace due to MSVC bugs preventing
|
||||
sg::detail::scope_guard from befriending a sg::make_scope_guard
|
||||
template instance in the parent namespace (see https://is.gd/xFfFhE). */
|
||||
|
||||
|
||||
/* --- The template specialization that actually defines the class --- */
|
||||
|
||||
template<typename Callback>
|
||||
class scope_guard<Callback> final
|
||||
{
|
||||
public:
|
||||
typedef Callback callback_type;
|
||||
|
||||
scope_guard(scope_guard&& other)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value);
|
||||
|
||||
~scope_guard() noexcept; // highlight noexcept dtor
|
||||
|
||||
void dismiss() noexcept;
|
||||
|
||||
public:
|
||||
scope_guard() = delete;
|
||||
scope_guard(const scope_guard&) = delete;
|
||||
scope_guard& operator=(const scope_guard&) = delete;
|
||||
scope_guard& operator=(scope_guard&&) = delete;
|
||||
|
||||
private:
|
||||
explicit scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value); /*
|
||||
meant for friends only */
|
||||
|
||||
friend scope_guard<Callback> make_scope_guard<Callback>(Callback&&)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value); /*
|
||||
only make_scope_guard can create scope_guards from scratch (i.e. non-move)
|
||||
*/
|
||||
|
||||
private:
|
||||
Callback m_callback;
|
||||
bool m_active;
|
||||
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/* --- Now the single public maker function --- */
|
||||
|
||||
using detail::make_scope_guard; // see comment on declaration above
|
||||
|
||||
} // namespace sg
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
sg::detail::scope_guard<Callback>::scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value)
|
||||
: m_callback(std::forward<Callback>(callback)) /* use () instead of {} because
|
||||
of DR 1467 (https://is.gd/WHmWuo), which still impacts older compilers
|
||||
(e.g. GCC 4.x and clang <=3.6, see https://godbolt.org/g/TE9tPJ and
|
||||
https://is.gd/Tsmh8G) */
|
||||
, m_active{true}
|
||||
{}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
sg::detail::scope_guard<Callback>::~scope_guard() noexcept
|
||||
{
|
||||
if(m_active)
|
||||
m_callback();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
sg::detail::scope_guard<Callback>::scope_guard(scope_guard&& other)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value)
|
||||
: m_callback(std::forward<Callback>(other.m_callback)) // idem
|
||||
, m_active{std::move(other.m_active)}
|
||||
{
|
||||
other.m_active = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
inline void sg::detail::scope_guard<Callback>::dismiss() noexcept
|
||||
{
|
||||
m_active = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Callback>
|
||||
inline auto sg::detail::make_scope_guard(Callback&& callback)
|
||||
noexcept(std::is_nothrow_constructible<Callback, Callback&&>::value)
|
||||
-> detail::scope_guard<Callback>
|
||||
{
|
||||
return detail::scope_guard<Callback>{std::forward<Callback>(callback)};
|
||||
}
|
||||
|
||||
#endif /* SCOPE_GUARD_HPP_ */
|
@ -490,19 +490,24 @@ Rectangle {
|
||||
walletCreatedFromDevice(success);
|
||||
}
|
||||
|
||||
function onWalletPassphraseNeeded(){
|
||||
function onWalletPassphraseNeeded(on_device){
|
||||
splash.close()
|
||||
|
||||
console.log(">>> wallet passphrase needed: ");
|
||||
passwordDialog.onAcceptedPassphraseCallback = function() {
|
||||
walletManager.onPassphraseEntered(passwordDialog.password);
|
||||
devicePassphraseDialog.onAcceptedCallback = function(passphrase) {
|
||||
walletManager.onPassphraseEntered(passphrase, false, false);
|
||||
creatingWalletDeviceSplash();
|
||||
}
|
||||
passwordDialog.onRejectedPassphraseCallback = function() {
|
||||
walletManager.onPassphraseEntered("", true);
|
||||
devicePassphraseDialog.onWalletEntryCallback = function() {
|
||||
walletManager.onPassphraseEntered("", true, false);
|
||||
creatingWalletDeviceSplash();
|
||||
}
|
||||
passwordDialog.openPassphraseDialog()
|
||||
devicePassphraseDialog.onRejectedCallback = function() {
|
||||
walletManager.onPassphraseEntered("", false, true);
|
||||
creatingWalletDeviceSplash();
|
||||
}
|
||||
|
||||
devicePassphraseDialog.open(on_device)
|
||||
}
|
||||
|
||||
function onDeviceButtonRequest(code){
|
||||
|
Loading…
Reference in New Issue
Block a user