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 SendCoinsRecipient* pthis = const_cast<SendCoinsRecipient*>(this);
66 std::string sAddress = pthis->address.toStdString();
67 std::string sLabel = pthis->label.toStdString();
68 std::string sMessage = pthis->message.toStdString();
69 std::string sPaymentRequest;
70 if (!fRead && pthis->paymentRequest.IsInitialized())
71 pthis->paymentRequest.SerializeToString(&sPaymentRequest);
72 std::string sAuthenticatedMerchant = pthis->authenticatedMerchant.toStdString();
74 READWRITE(pthis->nVersion);
75 nVersion = pthis->nVersion;
80 READWRITE(sPaymentRequest);
81 READWRITE(sAuthenticatedMerchant);
85 pthis->address = QString::fromStdString(sAddress);
86 pthis->label = QString::fromStdString(sLabel);
87 pthis->message = QString::fromStdString(sMessage);
88 if (!sPaymentRequest.empty())
89 pthis->paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
90 pthis->authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
95 /** Interface to Bitcoin wallet from Qt view code. */
96 class WalletModel : public QObject
101 explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
104 enum StatusCode // Returned by sendCoins
109 AmountExceedsBalance,
110 AmountWithFeeExceedsBalance,
112 TransactionCreationFailed, // Error returned when wallet is still locked
113 TransactionCommitFailed
116 enum EncryptionStatus
118 Unencrypted, // !wallet->IsCrypted()
119 Locked, // wallet->IsCrypted() && wallet->IsLocked()
120 Unlocked // wallet->IsCrypted() && !wallet->IsLocked()
123 OptionsModel *getOptionsModel();
124 AddressTableModel *getAddressTableModel();
125 TransactionTableModel *getTransactionTableModel();
126 RecentRequestsTableModel *getRecentRequestsTableModel();
128 qint64 getBalance(const CCoinControl *coinControl = NULL) const;
129 qint64 getUnconfirmedBalance() const;
130 qint64 getImmatureBalance() const;
131 qint64 getWatchBalance() const;
132 qint64 getWatchUnconfirmedBalance() const;
133 qint64 getWatchImmatureBalance() const;
134 EncryptionStatus getEncryptionStatus() const;
135 bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
137 // Check address for validity
138 bool validateAddress(const QString &address);
140 // Return status record for SendCoins, contains error id + information
141 struct SendCoinsReturn
143 SendCoinsReturn(StatusCode status = OK):
148 // prepare transaction for getting txfee before sending coins
149 SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL);
151 // Send coins to a list of recipients
152 SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
155 bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
156 // Passphrase only needed when unlocking
157 bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
158 bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
160 bool backupWallet(const QString &filename);
162 // RAI object for unlocking wallet, returned by requestUnlock()
166 UnlockContext(WalletModel *wallet, bool valid, bool relock);
169 bool isValid() const { return valid; }
171 // Copy operator and constructor transfer the context
172 UnlockContext(const UnlockContext& obj) { CopyFrom(obj); }
173 UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; }
177 mutable bool relock; // mutable, as it can be set to false by copying
179 void CopyFrom(const UnlockContext& rhs);
182 UnlockContext requestUnlock();
184 bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
185 void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
186 bool isSpent(const COutPoint& outpoint) const;
187 void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
189 bool isLockedCoin(uint256 hash, unsigned int n) const;
190 void lockCoin(COutPoint& output);
191 void unlockCoin(COutPoint& output);
192 void listLockedCoins(std::vector<COutPoint>& vOutpts);
194 void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
195 bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
199 bool fProcessingQueuedTransactions;
201 // Wallet has an options model for wallet-specific options
202 // (transaction fee, for example)
203 OptionsModel *optionsModel;
205 AddressTableModel *addressTableModel;
206 TransactionTableModel *transactionTableModel;
207 RecentRequestsTableModel *recentRequestsTableModel;
209 // Cache some values to be able to detect changes
210 qint64 cachedBalance;
211 qint64 cachedUnconfirmedBalance;
212 qint64 cachedImmatureBalance;
213 qint64 cachedWatchOnlyBalance;
214 qint64 cachedWatchUnconfBalance;
215 qint64 cachedWatchImmatureBalance;
216 EncryptionStatus cachedEncryptionStatus;
221 void subscribeToCoreSignals();
222 void unsubscribeFromCoreSignals();
223 void checkBalanceChanged();
226 // Signal that balance in wallet changed
227 void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance,
228 qint64 watchOnlyBalance, qint64 watchUnconfBalance, qint64 watchImmatureBalance);
230 // Encryption status of wallet changed
231 void encryptionStatusChanged(int status);
233 // Signal emitted when wallet needs to be unlocked
234 // It is valid behaviour for listeners to keep the wallet locked after this signal;
235 // this means that the unlocking failed or was cancelled.
236 void requireUnlock();
238 // Fired when a message should be reported to the user
239 void message(const QString &title, const QString &message, unsigned int style);
241 // Coins sent: from wallet, to recipient, in (serialized) transaction:
242 void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
244 // Show progress dialog e.g. for rescan
245 void showProgress(const QString &title, int nProgress);
248 /* Wallet status might have changed */
250 /* New transaction, or transaction changed status */
251 void updateTransaction(const QString &hash, int status);
252 /* New, updated or removed address book entry */
253 void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
254 /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
255 void pollBalanceChanged();
256 /* Needed to update fProcessingQueuedTransactions through a QueuedConnection */
257 void setProcessingQueuedTransactions(bool value) { fProcessingQueuedTransactions = value; }
260 #endif // WALLETMODEL_H