walletmodel.h
1 // Copyright (c) 2011-2022 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 <support/allocators/secure.h> 14 15 #include <vector> 16 17 #include <QObject> 18 19 enum class OutputType; 20 21 class AddressTableModel; 22 class ClientModel; 23 class OptionsModel; 24 class PlatformStyle; 25 class RecentRequestsTableModel; 26 class SendCoinsRecipient; 27 class TransactionTableModel; 28 class WalletModelTransaction; 29 30 class CKeyID; 31 class COutPoint; 32 class CPubKey; 33 class uint256; 34 35 namespace interfaces { 36 class Node; 37 } // namespace interfaces 38 namespace wallet { 39 class CCoinControl; 40 } // namespace wallet 41 42 QT_BEGIN_NAMESPACE 43 class QTimer; 44 QT_END_NAMESPACE 45 46 /** Interface to Bitcoin wallet from Qt view code. */ 47 class WalletModel : public QObject 48 { 49 Q_OBJECT 50 51 public: 52 explicit WalletModel(std::unique_ptr<interfaces::Wallet> wallet, ClientModel& client_model, const PlatformStyle *platformStyle, QObject *parent = nullptr); 53 ~WalletModel(); 54 55 enum StatusCode // Returned by sendCoins 56 { 57 OK, 58 InvalidAmount, 59 InvalidAddress, 60 AmountExceedsBalance, 61 AmountWithFeeExceedsBalance, 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->IsCrypted() 71 Locked, // wallet->IsCrypted() && wallet->IsLocked() 72 Unlocked // wallet->IsCrypted() && !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(uint256 hash, uint256& new_hash); 133 bool 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_watch_only_changed; 166 std::unique_ptr<interfaces::Handler> m_handler_can_get_addrs_changed; 167 ClientModel* m_client_model; 168 interfaces::Node& m_node; 169 170 bool fHaveWatchOnly; 171 bool fForceCheckBalanceChanged{false}; 172 173 // Wallet has an options model for wallet-specific options 174 // (transaction fee, for example) 175 OptionsModel *optionsModel; 176 177 AddressTableModel* addressTableModel{nullptr}; 178 TransactionTableModel* transactionTableModel{nullptr}; 179 RecentRequestsTableModel* recentRequestsTableModel{nullptr}; 180 181 // Cache some values to be able to detect changes 182 interfaces::WalletBalances m_cached_balances; 183 EncryptionStatus cachedEncryptionStatus{Unencrypted}; 184 QTimer* timer; 185 186 // Block hash denoting when the last balance update was done. 187 uint256 m_cached_last_update_tip{}; 188 189 void subscribeToCoreSignals(); 190 void unsubscribeFromCoreSignals(); 191 void checkBalanceChanged(const interfaces::WalletBalances& new_balances); 192 193 Q_SIGNALS: 194 // Signal that balance in wallet changed 195 void balanceChanged(const interfaces::WalletBalances& balances); 196 197 // Encryption status of wallet changed 198 void encryptionStatusChanged(); 199 200 // Signal emitted when wallet needs to be unlocked 201 // It is valid behaviour for listeners to keep the wallet locked after this signal; 202 // this means that the unlocking failed or was cancelled. 203 void requireUnlock(); 204 205 // Fired when a message should be reported to the user 206 void message(const QString &title, const QString &message, unsigned int style); 207 208 // Coins sent: from wallet, to recipient, in (serialized) transaction: 209 void coinsSent(WalletModel* wallet, SendCoinsRecipient recipient, QByteArray transaction); 210 211 // Show progress dialog e.g. for rescan 212 void showProgress(const QString &title, int nProgress); 213 214 // Watch-only address added 215 void notifyWatchonlyChanged(bool fHaveWatchonly); 216 217 // Signal that wallet is about to be removed 218 void unload(); 219 220 // Notify that there are now keys in the keypool 221 void canGetAddressesChanged(); 222 223 void timerTimeout(); 224 225 public Q_SLOTS: 226 /* Starts a timer to periodically update the balance */ 227 void startPollBalance(); 228 229 /* Wallet status might have changed */ 230 void updateStatus(); 231 /* New transaction, or transaction changed status */ 232 void updateTransaction(); 233 /* New, updated or removed address book entry */ 234 void updateAddressBook(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status); 235 /* Watch-only added */ 236 void updateWatchOnlyFlag(bool fHaveWatchonly); 237 /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ 238 void pollBalanceChanged(); 239 }; 240 241 #endif // BITCOIN_QT_WALLETMODEL_H