You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

walletmodel.h 10KB

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