1 // Copyright (c) 2011-2014 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
8 #include "paymentrequestplus.h"
9 #include "walletmodeltransaction.h"
11 #include "allocators.h" /* for SecureString */
18 class AddressTableModel;
20 class RecentRequestsTableModel;
21 class TransactionTableModel;
22 class WalletModelTransaction;
36 class SendCoinsRecipient
39 explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
40 explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message):
41 address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
43 // If from an insecure payment request, this is used for storing
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!
51 // If from a payment request, this is used for storing the memo
54 // If from a payment request, paymentRequest.IsInitialized() will be true
55 PaymentRequestPlus paymentRequest;
56 // Empty if no authentication or invalid signature/cert/etc.
57 QString authenticatedMerchant;
59 static const int CURRENT_VERSION = 1;
64 template <typename T, typename Stream, typename Operation>
65 inline static size_t SerializationOp(T thisPtr, Stream& s, Operation ser_action, int nType, int nVersion) {
67 bool fRead = boost::is_same<Operation, CSerActionUnserialize>();
69 SendCoinsRecipient* pthis = const_cast<SendCoinsRecipient*>(thisPtr);
71 std::string sAddress = pthis->address.toStdString();
72 std::string sLabel = pthis->label.toStdString();
73 std::string sMessage = pthis->message.toStdString();
74 std::string sPaymentRequest;
75 if (!fRead && pthis->paymentRequest.IsInitialized())
76 pthis->paymentRequest.SerializeToString(&sPaymentRequest);
77 std::string sAuthenticatedMerchant = pthis->authenticatedMerchant.toStdString();
79 READWRITE(pthis->nVersion);
80 nVersion = pthis->nVersion;
83 READWRITE(thisPtr->amount);
85 READWRITE(sPaymentRequest);
86 READWRITE(sAuthenticatedMerchant);
90 pthis->address = QString::fromStdString(sAddress);
91 pthis->label = QString::fromStdString(sLabel);
92 pthis->message = QString::fromStdString(sMessage);
93 if (!sPaymentRequest.empty())
94 pthis->paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
95 pthis->authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
102 /** Interface to Bitcoin wallet from Qt view code. */
103 class WalletModel : public QObject
108 explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
111 enum StatusCode // Returned by sendCoins
116 AmountExceedsBalance,
117 AmountWithFeeExceedsBalance,
119 TransactionCreationFailed, // Error returned when wallet is still locked
120 TransactionCommitFailed
123 enum EncryptionStatus
125 Unencrypted, // !wallet->IsCrypted()
126 Locked, // wallet->IsCrypted() && wallet->IsLocked()
127 Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
130 OptionsModel *getOptionsModel();
131 AddressTableModel *getAddressTableModel();
132 TransactionTableModel *getTransactionTableModel();
133 RecentRequestsTableModel *getRecentRequestsTableModel();
135 qint64 getBalance(const CCoinControl *coinControl = NULL) const;
136 qint64 getUnconfirmedBalance() const;
137 qint64 getImmatureBalance() const;
138 bool haveWatchOnly() const;
139 qint64 getWatchBalance() const;
140 qint64 getWatchUnconfirmedBalance() const;
141 qint64 getWatchImmatureBalance() const;
142 EncryptionStatus getEncryptionStatus() const;
143 bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
145 // Check address for validity
146 bool validateAddress(const QString &address);
148 // Return status record for SendCoins, contains error id + information
149 struct SendCoinsReturn
151 SendCoinsReturn(StatusCode status = OK):
156 // prepare transaction for getting txfee before sending coins
157 SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL);
159 // Send coins to a list of recipients
160 SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
163 bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
164 // Passphrase only needed when unlocking
165 bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
166 bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
168 bool backupWallet(const QString &filename);
170 // RAI object for unlocking wallet, returned by requestUnlock()
174 UnlockContext(WalletModel *wallet, bool valid, bool relock);
177 bool isValid() const { return valid; }
179 // Copy operator and constructor transfer the context
180 UnlockContext(const UnlockContext& obj) { CopyFrom(obj); }
181 UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; }
185 mutable bool relock; // mutable, as it can be set to false by copying
187 void CopyFrom(const UnlockContext& rhs);
190 UnlockContext requestUnlock();
192 bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
193 void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
194 bool isSpent(const COutPoint& outpoint) const;
195 void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
197 bool isLockedCoin(uint256 hash, unsigned int n) const;
198 void lockCoin(COutPoint& output);
199 void unlockCoin(COutPoint& output);
200 void listLockedCoins(std::vector<COutPoint>& vOutpts);
202 void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
203 bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
207 bool fProcessingQueuedTransactions;
210 // Wallet has an options model for wallet-specific options
211 // (transaction fee, for example)
212 OptionsModel *optionsModel;
214 AddressTableModel *addressTableModel;
215 TransactionTableModel *transactionTableModel;
216 RecentRequestsTableModel *recentRequestsTableModel;
218 // Cache some values to be able to detect changes
219 qint64 cachedBalance;
220 qint64 cachedUnconfirmedBalance;
221 qint64 cachedImmatureBalance;
222 qint64 cachedWatchOnlyBalance;
223 qint64 cachedWatchUnconfBalance;
224 qint64 cachedWatchImmatureBalance;
225 EncryptionStatus cachedEncryptionStatus;
230 void subscribeToCoreSignals();
231 void unsubscribeFromCoreSignals();
232 void checkBalanceChanged();
235 // Signal that balance in wallet changed
236 void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
237 qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);
239 // Encryption status of wallet changed
240 void encryptionStatusChanged(int status);
242 // Signal emitted when wallet needs to be unlocked
243 // It is valid behaviour for listeners to keep the wallet locked after this signal;
244 // this means that the unlocking failed or was cancelled.
245 void requireUnlock();
247 // Fired when a message should be reported to the user
248 void message(const QString &title, const QString &message, unsigned int style);
250 // Coins sent: from wallet, to recipient, in (serialized) transaction:
251 void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
253 // Show progress dialog e.g. for rescan
254 void showProgress(const QString &title, int nProgress);
256 // Watch-only address added
257 void notifyWatchonlyChanged(bool fHaveWatchonly);
260 /* Wallet status might have changed */
262 /* New transaction, or transaction changed status */
263 void updateTransaction(const QString &hash, int status);
264 /* New, updated or removed address book entry */
265 void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
266 /* Watchonly added */
267 void updateWatchOnlyFlag(bool fHaveWatchonly);
268 /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
269 void pollBalanceChanged();
270 /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */
271 void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; }
274 #endif // WALLETMODEL_H