Bugfix: Unspendable inputs handling
[novacoin.git] / src / qt / walletmodel.h
1 #ifndef WALLETMODEL_H
2 #define WALLETMODEL_H
3
4 #include <QObject>
5 #include <vector>
6 #include <map>
7
8 #include "allocators.h" /* for SecureString */
9
10 class OptionsModel;
11 class AddressTableModel;
12 class TransactionTableModel;
13 class CWallet;
14 class CKeyID;
15 class CPubKey;
16 class COutput;
17 class COutPoint;
18 class uint256;
19 class CCoinControl;
20
21 QT_BEGIN_NAMESPACE
22 class QTimer;
23 QT_END_NAMESPACE
24
25 class SendCoinsRecipient
26 {
27 public:
28     QString address;
29     QString label;
30     qint64 amount;
31 };
32
33 /** Interface to Bitcoin wallet from Qt view code. */
34 class WalletModel : public QObject
35 {
36     Q_OBJECT
37
38 public:
39     explicit WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent = 0);
40     ~WalletModel();
41
42     enum StatusCode // Returned by sendCoins
43     {
44         OK,
45         InvalidAmount,
46         InvalidAddress,
47         AmountExceedsBalance,
48         AmountWithFeeExceedsBalance,
49         DuplicateAddress,
50         TransactionCreationFailed, // Error returned when wallet is still locked
51         TransactionCommitFailed,
52         Aborted
53     };
54
55     enum EncryptionStatus
56     {
57         Unencrypted,  // !wallet->IsCrypted()
58         Locked,       // wallet->IsCrypted() && wallet->IsLocked()
59         Unlocked      // wallet->IsCrypted() && !wallet->IsLocked()
60     };
61
62     OptionsModel *getOptionsModel();
63     AddressTableModel *getAddressTableModel();
64     TransactionTableModel *getTransactionTableModel();
65
66     qint64 getBalance() const;
67     qint64 getBalanceWatchOnly() const;
68     qint64 getStake() const;
69     qint64 getUnconfirmedBalance() const;
70     qint64 getImmatureBalance() const;
71     int getNumTransactions() const;
72     EncryptionStatus getEncryptionStatus() const;
73
74     // Check address for validity
75     bool validateAddress(const QString &address);
76
77     // Return status record for SendCoins, contains error id + information
78     struct SendCoinsReturn
79     {
80         SendCoinsReturn(StatusCode status=Aborted,
81                          qint64 fee=0,
82                          QString hex=QString()):
83             status(status), fee(fee), hex(hex) {}
84         StatusCode status;
85         qint64 fee; // is used in case status is "AmountWithFeeExceedsBalance"
86         QString hex; // is filled with the transaction hash if status is "OK"
87     };
88
89     // Send coins to a list of recipients
90     SendCoinsReturn sendCoins(const QList<SendCoinsRecipient> &recipients, const CCoinControl *coinControl=NULL);
91
92     // Wallet encryption
93     bool setWalletEncrypted(bool encrypted, const SecureString &passphrase);
94     // Passphrase only needed when unlocking
95     bool setWalletLocked(bool locked, const SecureString &passPhrase=SecureString());
96     bool changePassphrase(const SecureString &oldPass, const SecureString &newPass);
97     // Wallet backup
98     bool backupWallet(const QString &filename);
99
100     bool dumpWallet(const QString &filename);
101     bool importWallet(const QString &filename);
102
103     void getStakeWeight(quint64& nMinWeight, quint64& nMaxWeight, quint64& nWeight);
104     void getStakeWeightFromValue(const qint64& nTime, const qint64& nValue, quint64& nWeight);
105
106     // RAI object for unlocking wallet, returned by requestUnlock()
107     class UnlockContext
108     {
109     public:
110         UnlockContext(WalletModel *wallet, bool valid, bool relock);
111         ~UnlockContext();
112
113         bool isValid() const { return valid; }
114
115         // Copy operator and constructor transfer the context
116         UnlockContext(const UnlockContext& obj) { CopyFrom(obj); }
117         UnlockContext& operator=(const UnlockContext& rhs) { CopyFrom(rhs); return *this; }
118     private:
119         WalletModel *wallet;
120         bool valid;
121         mutable bool relock; // mutable, as it can be set to false by copying
122
123         void CopyFrom(const UnlockContext& rhs);
124     };
125
126     UnlockContext requestUnlock();
127
128     bool getPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
129     void getOutputs(const std::vector<COutPoint>& vOutpoints, std::vector<COutput>& vOutputs);
130     void listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const;
131     bool isLockedCoin(uint256 hash, unsigned int n) const;
132     void lockCoin(COutPoint& output);
133     void unlockCoin(COutPoint& output);
134     void listLockedCoins(std::vector<COutPoint>& vOutpts);
135
136 private:
137     CWallet *wallet;
138
139     // Wallet has an options model for wallet-specific options
140     // (transaction fee, for example)
141     OptionsModel *optionsModel;
142
143     AddressTableModel *addressTableModel;
144     TransactionTableModel *transactionTableModel;
145
146     // Cache some values to be able to detect changes
147     qint64 cachedBalance;
148     qint64 cachedStake;
149     qint64 cachedUnconfirmedBalance;
150     qint64 cachedImmatureBalance;
151     qint64 cachedNumTransactions;
152     EncryptionStatus cachedEncryptionStatus;
153     int cachedNumBlocks;
154
155     QTimer *pollTimer;
156
157     void subscribeToCoreSignals();
158     void unsubscribeFromCoreSignals();
159     void checkBalanceChanged();
160
161
162 public slots:
163     /* Wallet status might have changed */
164     void updateStatus();
165     /* New transaction, or transaction changed status */
166     void updateTransaction(const QString &hash, int status);
167     /* New, updated or removed address book entry */
168     void updateAddressBook(const QString &address, const QString &label, bool isMine, int status);
169     /* Current, immature or unconfirmed balance might have changed - emit 'balanceChanged' if so */
170     void pollBalanceChanged();
171
172 signals:
173     // Signal that balance in wallet changed
174     void balanceChanged(qint64 total, qint64 watchOnly, qint64 stake, qint64 unconfirmedBalance, qint64 immatureBalance);
175
176     // Number of transactions in wallet changed
177     void numTransactionsChanged(int count);
178
179     // Encryption status of wallet changed
180     void encryptionStatusChanged(int status);
181
182     // Signal emitted when wallet needs to be unlocked
183     // It is valid behaviour for listeners to keep the wallet locked after this signal;
184     // this means that the unlocking failed or was cancelled.
185     void requireUnlock();
186
187     // Asynchronous error notification
188     void error(const QString &title, const QString &message, bool modal);
189 };
190
191
192 #endif // WALLETMODEL_H