25#include <QApplication> 
   28#include <QMutexLocker> 
   41    , m_activity_thread(new QThread(this))
 
   42    , m_activity_worker(new QObject)
 
   43    , m_client_model(client_model)
 
   45    , m_platform_style(platform_style)
 
   46    , m_options_model(client_model.getOptionsModel())
 
   71    std::map<std::string, std::pair<bool, std::string>> wallets;
 
   76        auto it = wallets.find(wallet_model->wallet().getWalletName());
 
   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;
 
  125            if (wallet_model->wallet().getWalletName() == 
name) {
 
  140    wallet_model->moveToThread(thread());
 
  142    QMetaObject::invokeMethod(
this, [wallet_model, 
this] {
 
  143        wallet_model->setParent(
this);
 
  151    const bool called = QMetaObject::invokeMethod(wallet_model, 
"startPollBalance");
 
  157        QWidget* active_dialog = QApplication::activeModalWidget();
 
  158        if (active_dialog && 
dynamic_cast<QProgressDialog*
>(active_dialog) == 
nullptr) {
 
  159            connect(qApp, &QApplication::focusWindowChanged, wallet_model, [
this, wallet_model]() {
 
  160                if (!QApplication::activeModalWidget()) {
 
  163            }, Qt::QueuedConnection);
 
  167    }, Qt::QueuedConnection);
 
  191    : QObject(wallet_controller)
 
  192    , m_wallet_controller(wallet_controller)
 
  193    , m_parent_widget(parent_widget)
 
  201    progress_dialog->setAttribute(Qt::WA_DeleteOnClose);
 
  204    progress_dialog->setWindowTitle(title_text);
 
  205    progress_dialog->setLabelText(label_text);
 
  206    progress_dialog->setRange(0, 0);
 
  207    progress_dialog->setCancelButton(
nullptr);
 
  208    progress_dialog->setWindowModality(Qt::ApplicationModal);
 
  212    progress_dialog->setValue(0);
 
  214    if (show_minimized) progress_dialog->showMinimized();
 
  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());
 
  305    if (signers.size() > 1) {
 
  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…"),
 
  384        show_loading_minimized);
 
  386    QTimer::singleShot(0, 
worker(), [
this] {
 
  387        for (
auto& 
wallet : 
node().walletLoader().getWallets()) {
 
  391        QTimer::singleShot(0, 
this, [
this] { Q_EMIT 
finished(); });
 
  402    QString 
name = QString::fromStdString(wallet_name);
 
  406        tr(
"Restore Wallet"),
 
  409        tr(
"Restoring Wallet <b>%1</b>…").arg(
name.toHtmlEscaped()));
 
  411    QTimer::singleShot(0, 
worker(), [
this, backup_file, wallet_name] {
 
  434        QMessageBox::information(
m_parent_widget, tr(
"Restore wallet message"), QString::fromStdString(
Untranslated(
"Wallet restored successfully \n").translated));
 
  446    box.setWindowTitle(tr(
"Migrate wallet"));
 
  448    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" 
  449                "If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts.\n" 
  450                "If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts.\n\n" 
  451                "The migration process will create a backup of the wallet before migrating. This backup file will be named " 
  452                "<wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of " 
  453                "an incorrect migration, the backup can be restored with the \"Restore Wallet\" functionality."));
 
  454    box.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel);
 
  455    box.setDefaultButton(QMessageBox::Yes);
 
  456    if (box.exec() != QMessageBox::Yes) 
return;
 
  459    if (
node().walletLoader().isEncrypted(
name)) {
 
  462        if (dlg.exec() == QDialog::Rejected) 
return;
 
  467    QTimer::singleShot(0, 
worker(), [
this, 
name, passphrase] {
 
  472            if (res->watchonly_wallet_name) {
 
  475            if (res->solvables_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 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.
 
interfaces::Wallet & wallet() const
 
void coinsSent(WalletModel *wallet, SendCoinsRecipient recipient, QByteArray transaction)
 
QString getDisplayName() const
 
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)=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 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 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.