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