walletmodel.h raw
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
235