]>
Commit | Line | Data |
---|---|---|
f914f1a7 | 1 | // Copyright (c) 2011-2014 The Bitcoin Core developers |
78253fcb | 2 | // Distributed under the MIT software license, see the accompanying |
e592d43f WL |
3 | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | ||
84738627 PJ |
5 | #ifndef BITCOIN_QT_WALLETMODEL_H |
6 | #define BITCOIN_QT_WALLETMODEL_H | |
ef079e18 | 7 | |
51ed9ec9 BD |
8 | #include "paymentrequestplus.h" |
9 | #include "walletmodeltransaction.h" | |
94f778bd | 10 | |
d7d187e8 | 11 | #include "support/allocators/secure.h" |
ef079e18 | 12 | |
6a86c24d | 13 | #include <map> |
0689f46c PK |
14 | #include <vector> |
15 | ||
16 | #include <QObject> | |
51ed9ec9 | 17 | |
ef079e18 | 18 | class AddressTableModel; |
51ed9ec9 | 19 | class OptionsModel; |
666893b1 | 20 | class RecentRequestsTableModel; |
6c1bf199 | 21 | class TransactionTableModel; |
9e8904f6 | 22 | class WalletModelTransaction; |
0689f46c PK |
23 | |
24 | class CCoinControl; | |
6a86c24d | 25 | class CKeyID; |
6a86c24d | 26 | class COutPoint; |
0689f46c PK |
27 | class COutput; |
28 | class CPubKey; | |
51ed9ec9 | 29 | class CWallet; |
0689f46c | 30 | class uint256; |
51ed9ec9 | 31 | |
6c83a841 SE |
32 | QT_BEGIN_NAMESPACE |
33 | class QTimer; | |
34 | QT_END_NAMESPACE | |
35 | ||
52d3a481 | 36 | class SendCoinsRecipient |
a5e6d723 | 37 | { |
52d3a481 | 38 | public: |
292623ad | 39 | explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) { } |
a372168e | 40 | explicit SendCoinsRecipient(const QString &addr, const QString &label, const CAmount& amount, const QString &message): |
292623ad | 41 | address(addr), label(label), amount(amount), message(message), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION) {} |
a41d5fe0 | 42 | |
6715efb9 | 43 | // If from an unauthenticated payment request, this is used for storing |
c6c97e0f PK |
44 | // the addresses, e.g. address-A<br />address-B<br />address-C. |
45 | // Info: As we don't need to process addresses in here when using | |
46 | // payment requests, we can abuse it for displaying an address list. | |
47 | // Todo: This is a hack, should be replaced with a cleaner solution! | |
a5e6d723 WL |
48 | QString address; |
49 | QString label; | |
a372168e | 50 | CAmount amount; |
983cef48 | 51 | // If from a payment request, this is used for storing the memo |
03535acd | 52 | QString message; |
a41d5fe0 GA |
53 | |
54 | // If from a payment request, paymentRequest.IsInitialized() will be true | |
55 | PaymentRequestPlus paymentRequest; | |
c6c97e0f PK |
56 | // Empty if no authentication or invalid signature/cert/etc. |
57 | QString authenticatedMerchant; | |
8476d5d4 | 58 | |
292623ad CL |
59 | bool fSubtractFeeFromAmount; // memory only |
60 | ||
4bee715b | 61 | static const int CURRENT_VERSION = 1; |
8476d5d4 CL |
62 | int nVersion; |
63 | ||
3f6540ad | 64 | ADD_SERIALIZE_METHODS; |
3d796f89 | 65 | |
84881f8c | 66 | template <typename Stream, typename Operation> |
31e9a838 | 67 | inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { |
47eb7659 PW |
68 | std::string sAddress = address.toStdString(); |
69 | std::string sLabel = label.toStdString(); | |
70 | std::string sMessage = message.toStdString(); | |
8476d5d4 | 71 | std::string sPaymentRequest; |
47eb7659 PW |
72 | if (!ser_action.ForRead() && paymentRequest.IsInitialized()) |
73 | paymentRequest.SerializeToString(&sPaymentRequest); | |
74 | std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString(); | |
8476d5d4 | 75 | |
47eb7659 PW |
76 | READWRITE(this->nVersion); |
77 | nVersion = this->nVersion; | |
8476d5d4 CL |
78 | READWRITE(sAddress); |
79 | READWRITE(sLabel); | |
84881f8c | 80 | READWRITE(amount); |
8476d5d4 CL |
81 | READWRITE(sMessage); |
82 | READWRITE(sPaymentRequest); | |
83 | READWRITE(sAuthenticatedMerchant); | |
84 | ||
47eb7659 | 85 | if (ser_action.ForRead()) |
8476d5d4 | 86 | { |
47eb7659 PW |
87 | address = QString::fromStdString(sAddress); |
88 | label = QString::fromStdString(sLabel); | |
89 | message = QString::fromStdString(sMessage); | |
8476d5d4 | 90 | if (!sPaymentRequest.empty()) |
47eb7659 PW |
91 | paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size())); |
92 | authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant); | |
8476d5d4 | 93 | } |
3d796f89 | 94 | } |
a5e6d723 WL |
95 | }; |
96 | ||
af836ad5 | 97 | /** Interface to Bitcoin wallet from Qt view code. */ |
ef079e18 WL |
98 | class WalletModel : public QObject |
99 | { | |
100 | Q_OBJECT | |
32af5266 | 101 | |
ef079e18 | 102 | public: |
ee014e5b | 103 | explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0); |
ab1b288f | 104 | ~WalletModel(); |
ef079e18 | 105 | |
6c85cbec | 106 | enum StatusCode // Returned by sendCoins |
ef079e18 WL |
107 | { |
108 | OK, | |
109 | InvalidAmount, | |
110 | InvalidAddress, | |
111 | AmountExceedsBalance, | |
112 | AmountWithFeeExceedsBalance, | |
a5e6d723 | 113 | DuplicateAddress, |
6c85cbec | 114 | TransactionCreationFailed, // Error returned when wallet is still locked |
c1c9d5b4 | 115 | TransactionCommitFailed, |
1371e6f5 | 116 | AbsurdFee, |
6715efb9 | 117 | PaymentRequestExpired |
ef079e18 WL |
118 | }; |
119 | ||
ae8adeb9 WL |
120 | enum EncryptionStatus |
121 | { | |
122 | Unencrypted, // !wallet->IsCrypted() | |
123 | Locked, // wallet->IsCrypted() && wallet->IsLocked() | |
124 | Unlocked // wallet->IsCrypted() && !wallet->IsLocked() | |
125 | }; | |
126 | ||
ef079e18 WL |
127 | OptionsModel *getOptionsModel(); |
128 | AddressTableModel *getAddressTableModel(); | |
129 | TransactionTableModel *getTransactionTableModel(); | |
666893b1 | 130 | RecentRequestsTableModel *getRecentRequestsTableModel(); |
ef079e18 | 131 | |
a372168e MF |
132 | CAmount getBalance(const CCoinControl *coinControl = NULL) const; |
133 | CAmount getUnconfirmedBalance() const; | |
134 | CAmount getImmatureBalance() const; | |
939ed973 | 135 | bool haveWatchOnly() const; |
a372168e MF |
136 | CAmount getWatchBalance() const; |
137 | CAmount getWatchUnconfirmedBalance() const; | |
138 | CAmount getWatchImmatureBalance() const; | |
ae8adeb9 WL |
139 | EncryptionStatus getEncryptionStatus() const; |
140 | ||
a5e6d723 WL |
141 | // Check address for validity |
142 | bool validateAddress(const QString &address); | |
143 | ||
b0849613 | 144 | // Return status record for SendCoins, contains error id + information |
a5e6d723 WL |
145 | struct SendCoinsReturn |
146 | { | |
4a61c394 | 147 | SendCoinsReturn(StatusCode status = OK): |
9e8904f6 | 148 | status(status) {} |
a5e6d723 | 149 | StatusCode status; |
a5e6d723 WL |
150 | }; |
151 | ||
9e8904f6 | 152 | // prepare transaction for getting txfee before sending coins |
0689f46c | 153 | SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL); |
9e8904f6 | 154 | |
b0849613 | 155 | // Send coins to a list of recipients |
9e8904f6 | 156 | SendCoinsReturn sendCoins(WalletModelTransaction &transaction); |
b7bcaf94 WL |
157 | |
158 | // Wallet encryption | |
94f778bd | 159 | bool setWalletEncrypted(bool encrypted, const SecureString &passphrase); |
b7bcaf94 | 160 | // Passphrase only needed when unlocking |
94f778bd DN |
161 | bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString()); |
162 | bool changePassphrase(const SecureString &oldPass, const SecureString &newPass); | |
4efbda3f | 163 | // Wallet backup |
164 | bool backupWallet(const QString &filename); | |
b7bcaf94 WL |
165 | |
166 | // RAI object for unlocking wallet, returned by requestUnlock() | |
167 | class UnlockContext | |
168 | { | |
169 | public: | |
170 | UnlockContext(WalletModel *wallet, bool valid, bool relock); | |
171 | ~UnlockContext(); | |
172 | ||
173 | bool isValid() const { return valid; } | |
174 | ||
6c85cbec WL |
175 | // Copy operator and constructor transfer the context |
176 | UnlockContext(const UnlockContext& obj) { CopyFrom(obj); } | |
177 | UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; } | |
b7bcaf94 WL |
178 | private: |
179 | WalletModel *wallet; | |
180 | bool valid; | |
181 | mutable bool relock; // mutable, as it can be set to false by copying | |
182 | ||
183 | void CopyFrom(const UnlockContext& rhs); | |
184 | }; | |
185 | ||
186 | UnlockContext requestUnlock(); | |
187 | ||
6a86c24d CL |
188 | bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const; |
189 | void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs); | |
93a18a36 | 190 | bool isSpent(const COutPoint& outpoint) const; |
6a86c24d CL |
191 | void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const; |
192 | ||
193 | bool isLockedCoin(uint256 hash, unsigned int n) const; | |
194 | void lockCoin(COutPoint& output); | |
195 | void unlockCoin(COutPoint& output); | |
196 | void listLockedCoins(std::vector<COutPoint>& vOutpts); | |
197 | ||
8476d5d4 CL |
198 | void loadReceiveRequests(std::vector<std::string>& vReceiveRequests); |
199 | bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); | |
200 | ||
ef079e18 WL |
201 | private: |
202 | CWallet *wallet; | |
939ed973 | 203 | bool fHaveWatchOnly; |
80daee0f | 204 | bool fForceCheckBalanceChanged; |
ef079e18 WL |
205 | |
206 | // Wallet has an options model for wallet-specific options | |
207 | // (transaction fee, for example) | |
208 | OptionsModel *optionsModel; | |
209 | ||
210 | AddressTableModel *addressTableModel; | |
211 | TransactionTableModel *transactionTableModel; | |
666893b1 | 212 | RecentRequestsTableModel *recentRequestsTableModel; |
ef079e18 | 213 | |
6c85cbec | 214 | // Cache some values to be able to detect changes |
a372168e MF |
215 | CAmount cachedBalance; |
216 | CAmount cachedUnconfirmedBalance; | |
217 | CAmount cachedImmatureBalance; | |
218 | CAmount cachedWatchOnlyBalance; | |
219 | CAmount cachedWatchUnconfBalance; | |
220 | CAmount cachedWatchImmatureBalance; | |
ae8adeb9 | 221 | EncryptionStatus cachedEncryptionStatus; |
6c83a841 SE |
222 | int cachedNumBlocks; |
223 | ||
224 | QTimer *pollTimer; | |
5df0b03c | 225 | |
ab1b288f WL |
226 | void subscribeToCoreSignals(); |
227 | void unsubscribeFromCoreSignals(); | |
6c83a841 SE |
228 | void checkBalanceChanged(); |
229 | ||
e092f229 | 230 | Q_SIGNALS: |
6c85cbec | 231 | // Signal that balance in wallet changed |
a372168e MF |
232 | void balanceChanged(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance, |
233 | const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance); | |
6c85cbec | 234 | |
6c85cbec | 235 | // Encryption status of wallet changed |
ae8adeb9 | 236 | void encryptionStatusChanged(int status); |
6c85cbec WL |
237 | |
238 | // Signal emitted when wallet needs to be unlocked | |
239 | // It is valid behaviour for listeners to keep the wallet locked after this signal; | |
240 | // this means that the unlocking failed or was cancelled. | |
b7bcaf94 | 241 | void requireUnlock(); |
ef079e18 | 242 | |
c6c97e0f | 243 | // Fired when a message should be reported to the user |
3675588a | 244 | void message(const QString &title, const QString &message, unsigned int style); |
ef079e18 | 245 | |
a41d5fe0 GA |
246 | // Coins sent: from wallet, to recipient, in (serialized) transaction: |
247 | void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction); | |
248 | ||
39278369 CL |
249 | // Show progress dialog e.g. for rescan |
250 | void showProgress(const QString &title, int nProgress); | |
251 | ||
939ed973 CL |
252 | // Watch-only address added |
253 | void notifyWatchonlyChanged(bool fHaveWatchonly); | |
254 | ||
e092f229 | 255 | public Q_SLOTS: |
fe4a6550 WL |
256 | /* Wallet status might have changed */ |
257 | void updateStatus(); | |
258 | /* New transaction, or transaction changed status */ | |
023e63df | 259 | void updateTransaction(); |
fe4a6550 | 260 | /* New, updated or removed address book entry */ |
dcd0b077 | 261 | void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status); |
fbe0fcae | 262 | /* Watch-only added */ |
939ed973 | 263 | void updateWatchOnlyFlag(bool fHaveWatchonly); |
6c83a841 SE |
264 | /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */ |
265 | void pollBalanceChanged(); | |
ef079e18 WL |
266 | }; |
267 | ||
84738627 | 268 | #endif // BITCOIN_QT_WALLETMODEL_H |