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 int getNumTransactions() const;
132 EncryptionStatus getEncryptionStatus() const;
134 // Check address for validity
135 bool validateAddress(const QString &address);
137 // Return status record for SendCoins, contains error id + information
138 struct SendCoinsReturn
140 SendCoinsReturn(StatusCode status = OK):
145 // prepare transaction for getting txfee before sending coins
146 SendCoinsReturn prepareTransaction(WalletModelTransaction &transaction, const CCoinControl *coinControl = NULL);
148 // Send coins to a list of recipients
149 SendCoinsReturn sendCoins(WalletModelTransaction &transaction);
152 bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
153 // Passphrase only needed when unlocking
154 bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
155 bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
157 bool backupWallet(const QString &filename);
159 // RAI object for unlocking wallet, returned by requestUnlock()
163 UnlockContext(WalletModel *wallet, bool valid, bool relock);
166 bool isValid() const { return valid; }
168 // Copy operator and constructor transfer the context
169 UnlockContext(const UnlockContext& obj) { CopyFrom(obj); }
170 UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; }
174 mutable bool relock; // mutable, as it can be set to false by copying
176 void CopyFrom(const UnlockContext& rhs);
179 UnlockContext requestUnlock();
181 bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
182 void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
183 bool isSpent(const COutPoint& outpoint) const;
184 void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
186 bool isLockedCoin(uint256 hash, unsigned int n) const;
187 void lockCoin(COutPoint& output);
188 void unlockCoin(COutPoint& output);
189 void listLockedCoins(std::vector<COutPoint>& vOutpts);
191 void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
192 bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
197 // Wallet has an options model for wallet-specific options
198 // (transaction fee, for example)
199 OptionsModel *optionsModel;
201 AddressTableModel *addressTableModel;
202 TransactionTableModel *transactionTableModel;
203 RecentRequestsTableModel *recentRequestsTableModel;
205 // Cache some values to be able to detect changes
206 qint64 cachedBalance;
207 qint64 cachedUnconfirmedBalance;
208 qint64 cachedImmatureBalance;
209 qint64 cachedNumTransactions;
210 EncryptionStatus cachedEncryptionStatus;
215 void subscribeToCoreSignals();
216 void unsubscribeFromCoreSignals();
217 void checkBalanceChanged();
220 // Signal that balance in wallet changed
221 void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
223 // Number of transactions in wallet changed
224 void numTransactionsChanged(int count);
226 // Encryption status of wallet changed
227 void encryptionStatusChanged(int status);
229 // Signal emitted when wallet needs to be unlocked
230 // It is valid behaviour for listeners to keep the wallet locked after this signal;
231 // this means that the unlocking failed or was cancelled.
232 void requireUnlock();
234 // Fired when a message should be reported to the user
235 void message(const QString &title, const QString &message, unsigned int style);
237 // Coins sent: from wallet, to recipient, in (serialized) transaction:
238 void coinsSent(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction);
240 // Show progress dialog e.g. for rescan
241 void showProgress(const QString &title, int nProgress);
244 /* Wallet status might have changed */
246 /* New transaction, or transaction changed status */
247 void updateTransaction(const QString &hash, int status);
248 /* New, updated or removed address book entry */
249 void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
250 /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
251 void pollBalanceChanged();
254 #endif // WALLETMODEL_H