1 // Copyright (c) 2011-2017 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.
5 #ifndef BITCOIN_QT_WALLETMODEL_H
6 #define BITCOIN_QT_WALLETMODEL_H
8 #include <qt/paymentrequestplus.h>
9 #include <qt/walletmodeltransaction.h>
11 #include <support/allocators/secure.h>
18 class AddressTableModel
;
21 class RecentRequestsTableModel
;
22 class TransactionTableModel
;
23 class WalletModelTransaction
;
37 class SendCoinsRecipient
40 explicit SendCoinsRecipient() : amount(0), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION
) { }
41 explicit SendCoinsRecipient(const QString
&addr
, const QString
&_label
, const CAmount
& _amount
, const QString
&_message
):
42 address(addr
), label(_label
), amount(_amount
), message(_message
), fSubtractFeeFromAmount(false), nVersion(SendCoinsRecipient::CURRENT_VERSION
) {}
44 // If from an unauthenticated payment request, this is used for storing
45 // the addresses, e.g. address-A<br />address-B<br />address-C.
46 // Info: As we don't need to process addresses in here when using
47 // payment requests, we can abuse it for displaying an address list.
48 // Todo: This is a hack, should be replaced with a cleaner solution!
52 // If from a payment request, this is used for storing the memo
55 // If from a payment request, paymentRequest.IsInitialized() will be true
56 PaymentRequestPlus paymentRequest
;
57 // Empty if no authentication or invalid signature/cert/etc.
58 QString authenticatedMerchant
;
60 bool fSubtractFeeFromAmount
; // memory only
62 static const int CURRENT_VERSION
= 1;
65 ADD_SERIALIZE_METHODS
;
67 template <typename Stream
, typename Operation
>
68 inline void SerializationOp(Stream
& s
, Operation ser_action
) {
69 std::string sAddress
= address
.toStdString();
70 std::string sLabel
= label
.toStdString();
71 std::string sMessage
= message
.toStdString();
72 std::string sPaymentRequest
;
73 if (!ser_action
.ForRead() && paymentRequest
.IsInitialized())
74 paymentRequest
.SerializeToString(&sPaymentRequest
);
75 std::string sAuthenticatedMerchant
= authenticatedMerchant
.toStdString();
77 READWRITE(this->nVersion
);
82 READWRITE(sPaymentRequest
);
83 READWRITE(sAuthenticatedMerchant
);
85 if (ser_action
.ForRead())
87 address
= QString::fromStdString(sAddress
);
88 label
= QString::fromStdString(sLabel
);
89 message
= QString::fromStdString(sMessage
);
90 if (!sPaymentRequest
.empty())
91 paymentRequest
.parse(QByteArray::fromRawData(sPaymentRequest
.data(), sPaymentRequest
.size()));
92 authenticatedMerchant
= QString::fromStdString(sAuthenticatedMerchant
);
97 /** Interface to Bitcoin wallet from Qt view code. */
98 class WalletModel
: public QObject
103 explicit WalletModel(const PlatformStyle
*platformStyle
, CWallet
*wallet
, OptionsModel
*optionsModel
, QObject
*parent
= 0);
106 enum StatusCode
// Returned by sendCoins
111 AmountExceedsBalance
,
112 AmountWithFeeExceedsBalance
,
114 TransactionCreationFailed
, // Error returned when wallet is still locked
115 TransactionCommitFailed
,
117 PaymentRequestExpired
120 enum EncryptionStatus
122 Unencrypted
, // !wallet->IsCrypted()
123 Locked
, // wallet->IsCrypted() && wallet->IsLocked()
124 Unlocked
// wallet->IsCrypted() && !wallet->IsLocked()
127 OptionsModel
*getOptionsModel();
128 AddressTableModel
*getAddressTableModel();
129 TransactionTableModel
*getTransactionTableModel();
130 RecentRequestsTableModel
*getRecentRequestsTableModel();
132 CAmount
getBalance(const CCoinControl
*coinControl
= nullptr) const;
133 CAmount
getUnconfirmedBalance() const;
134 CAmount
getImmatureBalance() const;
135 bool haveWatchOnly() const;
136 CAmount
getWatchBalance() const;
137 CAmount
getWatchUnconfirmedBalance() const;
138 CAmount
getWatchImmatureBalance() const;
139 EncryptionStatus
getEncryptionStatus() const;
141 // Check address for validity
142 bool validateAddress(const QString
&address
);
144 // Return status record for SendCoins, contains error id + information
145 struct SendCoinsReturn
147 SendCoinsReturn(StatusCode _status
= OK
, QString _reasonCommitFailed
= "")
149 reasonCommitFailed(_reasonCommitFailed
)
153 QString reasonCommitFailed
;
156 // prepare transaction for getting txfee before sending coins
157 SendCoinsReturn
prepareTransaction(WalletModelTransaction
&transaction
, const CCoinControl
& coinControl
);
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 bool IsSpendable(const CTxDestination
& dest
) const;
194 bool getPrivKey(const CKeyID
&address
, CKey
& vchPrivKeyOut
) const;
195 void getOutputs(const std::vector
<COutPoint
>& vOutpoints
, std::vector
<COutput
>& vOutputs
);
196 bool isSpent(const COutPoint
& outpoint
) const;
197 void listCoins(std::map
<QString
, std::vector
<COutput
> >& mapCoins
) const;
199 bool isLockedCoin(uint256 hash
, unsigned int n
) const;
200 void lockCoin(COutPoint
& output
);
201 void unlockCoin(COutPoint
& output
);
202 void listLockedCoins(std::vector
<COutPoint
>& vOutpts
);
204 void loadReceiveRequests(std::vector
<std::string
>& vReceiveRequests
);
205 bool saveReceiveRequest(const std::string
&sAddress
, const int64_t nId
, const std::string
&sRequest
);
207 bool transactionCanBeAbandoned(uint256 hash
) const;
208 bool abandonTransaction(uint256 hash
) const;
210 bool transactionCanBeBumped(uint256 hash
) const;
211 bool bumpFee(uint256 hash
);
213 static bool isWalletEnabled();
215 bool hdEnabled() const;
217 int getDefaultConfirmTarget() const;
222 bool fForceCheckBalanceChanged
;
224 // Wallet has an options model for wallet-specific options
225 // (transaction fee, for example)
226 OptionsModel
*optionsModel
;
228 AddressTableModel
*addressTableModel
;
229 TransactionTableModel
*transactionTableModel
;
230 RecentRequestsTableModel
*recentRequestsTableModel
;
232 // Cache some values to be able to detect changes
233 CAmount cachedBalance
;
234 CAmount cachedUnconfirmedBalance
;
235 CAmount cachedImmatureBalance
;
236 CAmount cachedWatchOnlyBalance
;
237 CAmount cachedWatchUnconfBalance
;
238 CAmount cachedWatchImmatureBalance
;
239 EncryptionStatus cachedEncryptionStatus
;
244 void subscribeToCoreSignals();
245 void unsubscribeFromCoreSignals();
246 void checkBalanceChanged();
249 // Signal that balance in wallet changed
250 void balanceChanged(const CAmount
& balance
, const CAmount
& unconfirmedBalance
, const CAmount
& immatureBalance
,
251 const CAmount
& watchOnlyBalance
, const CAmount
& watchUnconfBalance
, const CAmount
& watchImmatureBalance
);
253 // Encryption status of wallet changed
254 void encryptionStatusChanged(int status
);
256 // Signal emitted when wallet needs to be unlocked
257 // It is valid behaviour for listeners to keep the wallet locked after this signal;
258 // this means that the unlocking failed or was cancelled.
259 void requireUnlock();
261 // Fired when a message should be reported to the user
262 void message(const QString
&title
, const QString
&message
, unsigned int style
);
264 // Coins sent: from wallet, to recipient, in (serialized) transaction:
265 void coinsSent(CWallet
* wallet
, SendCoinsRecipient recipient
, QByteArray transaction
);
267 // Show progress dialog e.g. for rescan
268 void showProgress(const QString
&title
, int nProgress
);
270 // Watch-only address added
271 void notifyWatchonlyChanged(bool fHaveWatchonly
);
274 /* Wallet status might have changed */
276 /* New transaction, or transaction changed status */
277 void updateTransaction();
278 /* New, updated or removed address book entry */
279 void updateAddressBook(const QString
&address
, const QString
&label
, bool isMine
, const QString
&purpose
, int status
);
280 /* Watch-only added */
281 void updateWatchOnlyFlag(bool fHaveWatchonly
);
282 /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
283 void pollBalanceChanged();
286 #endif // BITCOIN_QT_WALLETMODEL_H