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