diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index ea146727c..4a1e0ad86 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -38,6 +38,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : ui->passEdit3->installEventFilter(this); ui->stakingCheckBox->setChecked(fWalletUnlockStakingOnly); + ui->stakingCheckBox->hide(); switch(mode) { @@ -47,6 +48,9 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : ui->passEdit1->hide(); setWindowTitle(tr("Encrypt wallet")); break; + case UnlockStaking: + ui->stakingCheckBox->setChecked(true); + ui->stakingCheckBox->show(); case Unlock: // Ask passphrase ui->stakingCheckBox->setChecked(false); ui->stakingCheckBox->show(); @@ -154,6 +158,7 @@ void AskPassphraseDialog::accept() QDialog::reject(); // Cancelled } } break; + case UnlockStaking: case Unlock: if(!model->setWalletLocked(false, oldpass)) { @@ -210,6 +215,7 @@ void AskPassphraseDialog::textChanged() case Encrypt: // New passphrase x2 acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty(); break; + case UnlockStaking: case Unlock: // Old passphrase x1 case Decrypt: acceptable = !ui->passEdit1->text().isEmpty(); diff --git a/src/qt/askpassphrasedialog.h b/src/qt/askpassphrasedialog.h index 40f22abe2..7414fdfe6 100644 --- a/src/qt/askpassphrasedialog.h +++ b/src/qt/askpassphrasedialog.h @@ -23,6 +23,7 @@ public: enum Mode { Encrypt, /**< Ask passphrase twice and encrypt */ Unlock, /**< Ask passphrase and unlock */ + UnlockStaking, /**< Ask passphrase and unlock staking only */ ChangePass, /**< Ask old passphrase + new passphrase twice */ Decrypt, /**< Ask passphrase and decrypt wallet */ }; diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui index dce4b8883..5945a1316 100644 --- a/src/qt/forms/askpassphrasedialog.ui +++ b/src/qt/forms/askpassphrasedialog.ui @@ -120,9 +120,6 @@ * Tick for staking only - - false - diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index 70eb9a02e..a5af522ea 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -172,6 +172,9 @@ void WalletFrame::changePassphrase() void WalletFrame::unlockWallet() { + QObject* object = sender(); + QString objectName = object ? object->objectName() : ""; + bool fromMenu = objectName == "unlockWalletAction"; WalletView *walletView = currentWalletView(); if (walletView) walletView->unlockWallet(); diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 41823f507..e3638246c 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -267,14 +267,16 @@ void WalletView::changePassphrase() dlg.exec(); } -void WalletView::unlockWallet() +void WalletView::unlockWallet(bool fromMenu) { if(!walletModel) return; // Unlock wallet when requested by wallet model if (walletModel->getEncryptionStatus() == WalletModel::Locked) { - AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); + AskPassphraseDialog::Mode mode = fromMenu ? + AskPassphraseDialog::UnlockStaking : AskPassphraseDialog::Unlock; + AskPassphraseDialog dlg(mode, this); dlg.setModel(walletModel); dlg.exec(); } diff --git a/src/qt/walletview.h b/src/qt/walletview.h index 47295b5a4..af3292096 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -98,7 +98,7 @@ public Q_SLOTS: /** Change encrypted wallet passphrase */ void changePassphrase(); /** Ask for passphrase to unlock wallet temporarily */ - void unlockWallet(); + void unlockWallet(bool fromMenu = false); void lockWallet(); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index ebdd187b6..8ae006b99 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -56,6 +56,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listaccounts", 0 }, { "listaccounts", 1 }, { "walletpassphrase", 1 }, + { "walletpassphrase", 2 }, { "getblocktemplate", 0 }, { "listsinceblock", 1 }, { "listsinceblock", 2 }, diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b12986098..9cc756b74 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -122,6 +122,8 @@ UniValue importprivkey(const UniValue& params, bool fHelp) bool fGood = vchSecret.SetString(strSecret); if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key encoding"); + if (fWalletUnlockStakingOnly) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for staking only."); CKey key = vchSecret.GetKey(); if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); @@ -547,6 +549,8 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); } + if (fWalletUnlockStakingOnly) + throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for staking only."); const CKeyID *keyID = boost::get(&dest); if (!keyID) { throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 27cf38056..c8da71c5c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -380,6 +380,12 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr if (nValue > curBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + if (fWalletUnlockStakingOnly) + { + string strError = _("Error: Wallet unlocked for staking only, unable to create transaction."); + throw JSONRPCError(RPC_WALLET_ERROR, strError); + } + // Parse Bitcoin address CScript scriptPubKey = GetScriptForDestination(address); @@ -1885,7 +1891,7 @@ UniValue walletpassphrase(const UniValue& params, bool fHelp) if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; - if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) + if (pwalletMain->IsCrypted() && (fHelp || params.size() < 2 || params.size() > 3)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"