/ src / qt / walletmodel.h
walletmodel.h
  1  // Copyright (c) 2011-present The Bitcoin Core developers
  2  // Distributed under the MIT software license, see the accompanying
  3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4  
  5  #ifndef BITCOIN_QT_WALLETMODEL_H
  6  #define BITCOIN_QT_WALLETMODEL_H
  7  
  8  #include <key.h>
  9  
 10  #include <qt/walletmodeltransaction.h>
 11  
 12  #include <interfaces/wallet.h>
 13  #include <primitives/transaction_identifier.h>
 14  #include <support/allocators/secure.h>
 15  
 16  #include <vector>
 17  
 18  #include <QObject>
 19  
 20  enum class OutputType;
 21  
 22  class AddressTableModel;
 23  class ClientModel;
 24  class OptionsModel;
 25  class PlatformStyle;
 26  class RecentRequestsTableModel;
 27  class SendCoinsRecipient;
 28  class TransactionTableModel;
 29  class WalletModelTransaction;
 30  
 31  class CKeyID;
 32  class COutPoint;
 33  class CPubKey;
 34  class uint256;
 35  
 36  namespace interfaces {
 37  class Node;
 38  } // namespace interfaces
 39  namespace wallet {
 40  class CCoinControl;
 41  } // namespace wallet
 42  
 43  QT_BEGIN_NAMESPACE
 44  class QTimer;
 45  QT_END_NAMESPACE
 46  
 47  /** Interface to Bitcoin wallet from Qt view code. */
 48  class WalletModel : public QObject
 49  {
 50      Q_OBJECT
 51  
 52  public:
 53      explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent = nullptr);
 54      ~WalletModel();
 55  
 56      enum StatusCode // Returned by sendCoins
 57      {
 58          OK,
 59          InvalidAmount,
 60          InvalidAddress,
 61          AmountExceedsBalance,
 62          DuplicateAddress,
 63          TransactionCreationFailed, // Error returned when wallet is still locked
 64          AbsurdFee
 65      };
 66  
 67      enum EncryptionStatus
 68      {
 69          NoKeys,       // wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)
 70          Unencrypted,  // !wallet->HasEncryptionKeys()
 71          Locked,       // wallet->HasEncryptionKeys() && wallet->IsLocked()
 72          Unlocked      // wallet->HasEncryptionKeys() && !wallet->IsLocked()
 73      };
 74  
 75      OptionsModel* getOptionsModel() const;
 76      AddressTableModel* getAddressTableModel() const;
 77      TransactionTableModel* getTransactionTableModel() const;
 78      RecentRequestsTableModel* getRecentRequestsTableModel() const;
 79  
 80      EncryptionStatus getEncryptionStatus() const;
 81  
 82      // Check address for validity
 83      bool validateAddress(const QString& address) const;
 84  
 85      // Return status record for SendCoins, contains error id + information
 86      struct SendCoinsReturn
 87      {
 88          SendCoinsReturn(StatusCode _status = OK, QString _reasonCommitFailed = "")
 89              : status(_status),
 90                reasonCommitFailed(_reasonCommitFailed)
 91          {
 92          }
 93          StatusCode status;
 94          QString reasonCommitFailed;
 95      };
 96  
 97      // prepare transaction for getting txfee before sending coins
 98      SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const wallet::CCoinControl& coinControl);
 99  
100      // Send coins to a list of recipients
101      void sendCoins(WalletModelTransaction& transaction);
102  
103      // Wallet encryption
104      bool setWalletEncrypted(const SecureString& passphrase);
105      // Passphrase only needed when unlocking
106      bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
107      bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
108  
109      // RAII object for unlocking wallet, returned by requestUnlock()
110      class UnlockContext
111      {
112      public:
113          UnlockContext(WalletModel *wallet, bool valid, bool relock);
114          ~UnlockContext();
115  
116          bool isValid() const { return valid; }
117  
118          // Disable unused copy/move constructors/assignments explicitly.
119          UnlockContext(const UnlockContext&) = delete;
120          UnlockContext(UnlockContext&&) = delete;
121          UnlockContext& operator=(const UnlockContext&) = delete;
122          UnlockContext& operator=(UnlockContext&&) = delete;
123  
124      private:
125          WalletModel *wallet;
126          const bool valid;
127          const bool relock;
128      };
129  
130      UnlockContext requestUnlock();
131  
132      bool bumpFee(Txid hash, Txid& new_hash);
133      void displayAddress(std::string sAddress) const;
134  
135      static bool isWalletEnabled();
136  
137      interfaces::Node& node() const { return m_node; }
138      interfaces::Wallet& wallet() const { return *m_wallet; }
139      ClientModel& clientModel() const { return *m_client_model; }
140      void setClientModel(ClientModel* client_model);
141  
142      QString getWalletName() const;
143      QString getDisplayName() const;
144  
145      bool isMultiwallet() const;
146  
147      void refresh(bool pk_hash_only = false);
148  
149      uint256 getLastBlockProcessed() const;
150  
151      // Retrieve the cached wallet balance
152      interfaces::WalletBalances getCachedBalance() const;
153  
154      // If coin control has selected outputs, searches the total amount inside the wallet.
155      // Otherwise, uses the wallet's cached available balance.
156      CAmount getAvailableBalance(const wallet::CCoinControl* control);
157  
158  private:
159      std::unique_ptr<interfaces::Wallet> m_wallet;
160      std::unique_ptr<interfaces::Handler> m_handler_unload;
161      std::unique_ptr<interfaces::Handler> m_handler_status_changed;
162      std::unique_ptr<interfaces::Handler> m_handler_address_book_changed;
163      std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
164      std::unique_ptr<interfaces::Handler> m_handler_show_progress;
165      std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed;
166      ClientModel* m_client_model;
167      interfaces::Node& m_node;
168  
169      bool fForceCheckBalanceChanged{false};
170  
171      // Wallet has an options model for wallet-specific options
172      // (transaction fee, for example)
173      OptionsModel *optionsModel;
174  
175      AddressTableModel* addressTableModel{nullptr};
176      TransactionTableModel* transactionTableModel{nullptr};
177      RecentRequestsTableModel* recentRequestsTableModel{nullptr};
178  
179      // Cache some values to be able to detect changes
180      interfaces::WalletBalances m_cached_balances;
181      EncryptionStatus cachedEncryptionStatus{Unencrypted};
182      QTimer* timer;
183  
184      // Block hash denoting when the last balance update was done.
185      uint256 m_cached_last_update_tip{};
186  
187      void subscribeToCoreSignals();
188      void unsubscribeFromCoreSignals();
189      void checkBalanceChanged(const interfaces::WalletBalances& new_balances);
190  
191  Q_SIGNALS:
192      // Signal that balance in wallet changed
193      void balanceChanged(const interfaces::WalletBalances& balances);
194  
195      // Encryption status of wallet changed
196      void encryptionStatusChanged();
197  
198      // Signal emitted when wallet needs to be unlocked
199      // It is valid behaviour for listeners to keep the wallet locked after this signal;
200      // this means that the unlocking failed or was cancelled.
201      void requireUnlock();
202  
203      // Fired when a message should be reported to the user
204      void message(const QString &title, const QString &message, unsigned int style);
205  
206      // Coins sent: from wallet, to recipient, in (serialized) transaction:
207      void coinsSent(WalletModel* wallet, SendCoinsRecipient recipient, QByteArray transaction);
208  
209      // Show progress dialog e.g. for rescan
210      void showProgress(const QString &title, int nProgress);
211  
212      // Signal that wallet is about to be removed
213      void unload();
214  
215      // Notify that there are now keys in the keypool
216      void canGetAddressesChanged();
217  
218      void timerTimeout();
219  
220  public Q_SLOTS:
221      /* Starts a timer to periodically update the balance */
222      void startPollBalance();
223  
224      /* Wallet status might have changed */
225      void updateStatus();
226      /* New transaction, or transaction changed status */
227      void updateTransaction();
228      /* New, updated or removed address book entry */
229      void updateAddressBook(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status);
230      /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
231      void pollBalanceChanged();
232  };
233  
234  #endif // BITCOIN_QT_WALLETMODEL_H