25#include <QApplication>
28#include <QMutexLocker>
42 , m_activity_worker(
new QObject)
71 std::map<std::string, std::pair<bool, std::string>>
wallets;
77 if (it !=
wallets.end()) it->second.first =
true;
92 QMessageBox
box(parent);
93 box.setWindowTitle(
tr(
"Close wallet"));
95 box.setInformativeText(
tr(
"Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled."));
96 box.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel);
97 box.setDefaultButton(QMessageBox::Yes);
98 if (
box.exec() != QMessageBox::Yes)
return;
105 QMessageBox::StandardButton
button = QMessageBox::question(parent,
tr(
"Close all wallets"),
106 tr(
"Are you sure you wish to close all wallets?"),
107 QMessageBox::Yes|QMessageBox::Cancel,
109 if (
button != QMessageBox::Yes)
return;
160 if (!QApplication::activeModalWidget()) {
163 }, Qt::QueuedConnection);
167 }, Qt::QueuedConnection);
258 flags |= WALLET_FLAG_DESCRIPTORS;
260 flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
263 flags |= WALLET_FLAG_BLANK_WALLET;
266 flags |= WALLET_FLAG_EXTERNAL_SIGNER;
299 std::vector<std::unique_ptr<interfaces::ExternalSigner>>
signers;
302 }
catch (
const std::runtime_error&
e) {
303 QMessageBox::critical(
nullptr,
tr(
"Can't list signers"),
e.what());
306 QMessageBox::critical(
nullptr,
tr(
"Too many external signers found"), QString::fromStdString(
"More than one external signer found. Please connect only one at a time."));
356 tr(
"Opening Wallet <b>%1</b>…").
arg(
name.toHtmlEscaped()));
358 QTimer::singleShot(0,
worker(), [
this, path] {
383 tr(
"Loading wallets…"),
386 QTimer::singleShot(0,
worker(), [
this] {
402 QString name = QString::fromStdString(wallet_name);
406 tr(
"Restore Wallet"),
409 tr(
"Restoring Wallet <b>%1</b>…").
arg(
name.toHtmlEscaped()));
434 QMessageBox::information(
m_parent_widget,
tr(
"Restore wallet message"), QString::fromStdString(
Untranslated(
"Wallet restored successfully \n").translated));
445 if (
node().walletLoader().isEncrypted(
name)) {
448 if (
dlg.exec() == QDialog::Rejected)
return;
458 if (
res->watchonly_wallet_name) {
461 if (
res->solvables_wallet_name) {
477 box.setWindowTitle(
tr(
"Migrate wallet"));
479 box.setInformativeText(
tr(
"Migrating the wallet will convert this wallet to one or more descriptor wallets. A new wallet backup will need to be made.\n"
480 "If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts.\n"
481 "If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts.\n\n"
482 "The migration process will create a backup of the wallet before migrating. This backup file will be named "
483 "<wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of "
484 "an incorrect migration, the backup can be restored with the \"Restore Wallet\" functionality."));
485 box.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel);
486 box.setDefaultButton(QMessageBox::Yes);
487 if (
box.exec() != QMessageBox::Yes)
return;
496 box.setWindowTitle(
tr(
"Restore and Migrate wallet"));
498 box.setInformativeText(
tr(
"Restoring the wallet will copy the backup file to the wallets directory and place it in the standard "
499 "wallet directory layout. The original file will not be modified.\n\n"
500 "Migrating the wallet will convert the restored wallet to one or more descriptor wallets. A new wallet backup will need to be made.\n"
501 "If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts.\n"
502 "If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts.\n\n"
503 "The migration process will create a backup of the wallet before migrating. This backup file will be named "
504 "<wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of "
505 "an incorrect migration, the backup can be restored with the \"Restore Wallet\" functionality."));
506 box.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel);
507 box.setDefaultButton(QMessageBox::Yes);
508 if (
box.exec() != QMessageBox::Yes)
return;
512 tr(
"Restore Wallet"),
517 QTimer::singleShot(0,
worker(), [
this, path, wallet_name] {
525 QTimer::singleShot(0,
this, [
this, wallet_name] {
Multifunctional dialog to ask for passphrases.
@ Encrypt
Ask passphrase twice and encrypt.
@ UnlockMigration
Ask passphrase for unlocking during migration.
Model for Bitcoin network client.
virtual ~CreateWalletActivity()
AskPassphraseDialog * m_passphrase_dialog
CreateWalletDialog * m_create_wallet_dialog
SecureString m_passphrase
CreateWalletActivity(WalletController *wallet_controller, QWidget *parent_widget)
void created(WalletModel *wallet_model)
Dialog for creating wallets.
bool isMakeBlankWalletChecked() const
QString walletName() const
bool isDisablePrivateKeysChecked() const
bool isEncryptWalletChecked() const
void setSigners(const std::vector< std::unique_ptr< interfaces::ExternalSigner > > &signers)
bool isExternalSignerChecked() const
void load(bool show_loading_minimized)
LoadWalletsActivity(WalletController *wallet_controller, QWidget *parent_widget)
QString m_success_message
void do_migrate(const std::string &name)
void restore_and_migrate(const fs::path &path, const std::string &wallet_name)
void migrated(WalletModel *wallet_model)
void migrate(const std::string &path)
void opened(WalletModel *wallet_model)
OpenWalletActivity(WalletController *wallet_controller, QWidget *parent_widget)
void open(const std::string &path)
void restore(const fs::path &backup_file, const std::string &wallet_name)
void restored(WalletModel *wallet_model)
RestoreWalletActivity(WalletController *wallet_controller, QWidget *parent_widget)
WalletModel * m_wallet_model
std::vector< bilingual_str > m_warning_message
WalletController *const m_wallet_controller
interfaces::Node & node() const
void showProgressDialog(const QString &title_text, const QString &label_text, bool show_minimized=false)
bilingual_str m_error_message
WalletControllerActivity(WalletController *wallet_controller, QWidget *parent_widget)
QWidget *const m_parent_widget
Controller between interfaces::Node, WalletModel instances and the GUI.
WalletController(ClientModel &client_model, const PlatformStyle *platform_style, QObject *parent)
WalletModel * getOrCreateWallet(std::unique_ptr< interfaces::Wallet > wallet)
ClientModel & m_client_model
void removeAndDeleteWallet(WalletModel *wallet_model)
void walletAdded(WalletModel *wallet_model)
void closeAllWallets(QWidget *parent=nullptr)
std::unique_ptr< interfaces::Handler > m_handler_load_wallet
QThread *const m_activity_thread
void coinsSent(WalletModel *wallet_model, SendCoinsRecipient recipient, QByteArray transaction)
QObject *const m_activity_worker
void walletRemoved(WalletModel *wallet_model)
const PlatformStyle *const m_platform_style
interfaces::Node & m_node
void closeWallet(WalletModel *wallet_model, QWidget *parent=nullptr)
std::map< std::string, std::pair< bool, std::string > > listWalletDir() const
Returns all wallet names in the wallet dir mapped to whether the wallet is loaded.
void removeWallet(WalletModel *wallet_model)
Starts the wallet closure procedure.
std::vector< WalletModel * > m_wallets
Interface to Bitcoin wallet from Qt view code.
void coinsSent(WalletModel *wallet, SendCoinsRecipient recipient, QByteArray transaction)
virtual WalletLoader & walletLoader()=0
Get wallet loader.
virtual std::vector< std::unique_ptr< ExternalSigner > > listExternalSigners()=0
Return list of external signers (attached devices which can sign transactions).
virtual util::Result< std::unique_ptr< Wallet > > restoreWallet(const fs::path &backup_file, const std::string &wallet_name, std::vector< bilingual_str > &warnings, bool load_after_restore)=0
Restore backup wallet.
virtual util::Result< std::unique_ptr< Wallet > > createWallet(const std::string &name, const SecureString &passphrase, uint64_t wallet_creation_flags, std::vector< bilingual_str > &warnings)=0
Create new wallet.
virtual std::vector< std::unique_ptr< Wallet > > getWallets()=0
Return interfaces for accessing wallets (if any).
virtual util::Result< WalletMigrationResult > migrateWallet(const std::string &name, const SecureString &passphrase)=0
Migrate a wallet.
virtual std::vector< std::pair< std::string, std::string > > listWalletDir()=0
Return available wallets in wallet directory.
virtual util::Result< std::unique_ptr< Wallet > > loadWallet(const std::string &name, std::vector< bilingual_str > &warnings)=0
Load existing wallet.
virtual std::unique_ptr< Handler > handleLoadWallet(LoadWalletFn fn)=0
static std::string PathToString(const path &path)
Convert path object to a byte string.
static const int MAX_PASSPHRASE_SIZE
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
QString WalletDisplayName(const QString &name)
QString HtmlEscape(const QString &str, bool fMultiLine)
void PolishProgressDialog(QProgressDialog *dialog)
void ThreadRename(const std::string &)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
bilingual_str ErrorString(const Result< T > &result)
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.