Split off WalletModel from ClientModel, to be able to support multi-wallets in future
authorWladimir J. van der Laan <laanwj@gmail.com>
Thu, 30 Jun 2011 16:05:29 +0000 (18:05 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Thu, 30 Jun 2011 16:05:29 +0000 (18:05 +0200)
bitcoin-qt.pro
src/qt/bitcoin.cpp
src/qt/bitcoingui.cpp
src/qt/bitcoingui.h
src/qt/clientmodel.cpp
src/qt/clientmodel.h
src/qt/sendcoinsdialog.cpp
src/qt/sendcoinsdialog.h
src/qt/walletmodel.cpp [new file with mode: 0644]
src/qt/walletmodel.h [new file with mode: 0644]

index 76841f8..539c326 100644 (file)
@@ -74,7 +74,8 @@ HEADERS += src/qt/bitcoingui.h \
     src/wallet.h \
     src/keystore.h \
     src/qt/transactionfilterproxy.h \
-    src/qt/transactionview.h
+    src/qt/transactionview.h \
+    src/qt/walletmodel.h
 SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
     src/qt/transactiontablemodel.cpp \
     src/qt/addresstablemodel.cpp \
@@ -109,7 +110,8 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
     src/wallet.cpp \
     src/keystore.cpp \
     src/qt/transactionfilterproxy.cpp \
-    src/qt/transactionview.cpp
+    src/qt/transactionview.cpp \
+    src/qt/walletmodel.cpp
 
 RESOURCES += \
     src/qt/bitcoin.qrc
index c31be1b..397af5f 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include "bitcoingui.h"
 #include "clientmodel.h"
+#include "walletmodel.h"
 
 #include "headers.h"
 #include "init.h"
@@ -113,9 +114,11 @@ int main(int argc, char *argv[])
         if(AppInit2(argc, argv))
         {
             BitcoinGUI window;
-            ClientModel model(pwalletMain);
+            ClientModel clientModel(pwalletMain);
+            WalletModel walletModel(pwalletMain);
             guiref = &window;
-            window.setModel(&model);
+            window.setClientModel(&clientModel);
+            window.setWalletModel(&walletModel);
 
             window.show();
 
index f5885db..2b1990b 100644 (file)
@@ -10,6 +10,7 @@
 #include "optionsdialog.h"
 #include "aboutdialog.h"
 #include "clientmodel.h"
+#include "walletmodel.h"
 #include "guiutil.h"
 #include "editaddressdialog.h"
 #include "optionsmodel.h"
 #include <iostream>
 
 BitcoinGUI::BitcoinGUI(QWidget *parent):
-    QMainWindow(parent), trayIcon(0)
+    QMainWindow(parent),
+    clientModel(0),
+    walletModel(0),
+    trayIcon(0)
 {
     resize(850, 550);
     setWindowTitle(tr("Bitcoin"));
@@ -174,34 +178,43 @@ void BitcoinGUI::createActions()
     connect(openBitcoin, SIGNAL(triggered()), this, SLOT(show()));
 }
 
-void BitcoinGUI::setModel(ClientModel *model)
+void BitcoinGUI::setClientModel(ClientModel *clientModel)
 {
-    this->model = model;
+    this->clientModel = clientModel;
 
     // Keep up to date with client
-    setBalance(model->getBalance());
-    connect(model, SIGNAL(balanceChanged(qint64)), this, SLOT(setBalance(qint64)));
+    setNumConnections(clientModel->getNumConnections());
+    connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
 
-    setNumConnections(model->getNumConnections());
-    connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
+    setNumBlocks(clientModel->getNumBlocks());
+    connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
 
-    setNumTransactions(model->getNumTransactions());
-    connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
+    // Report errors from network/worker thread
+    connect(clientModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
+}
+
+void BitcoinGUI::setWalletModel(WalletModel *walletModel)
+{
+    this->walletModel = walletModel;
 
-    setNumBlocks(model->getNumBlocks());
-    connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+    // Keep up to date with wallet
+    setBalance(walletModel->getBalance());
+    connect(walletModel, SIGNAL(balanceChanged(qint64)), this, SLOT(setBalance(qint64)));
 
-    setAddress(model->getAddressTableModel()->getDefaultAddress());
-    connect(model->getAddressTableModel(), SIGNAL(defaultAddressChanged(QString)), this, SLOT(setAddress(QString)));
+    setNumTransactions(walletModel->getNumTransactions());
+    connect(walletModel, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
 
-    // Report errors from network/worker thread
-    connect(model, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));    
+    setAddress(walletModel->getAddressTableModel()->getDefaultAddress());
+    connect(walletModel->getAddressTableModel(), SIGNAL(defaultAddressChanged(QString)), this, SLOT(setAddress(QString)));
+
+    // Report errors from wallet thread
+    connect(walletModel, SIGNAL(error(QString,QString)), this, SLOT(error(QString,QString)));
 
     // Put transaction list in tabs
-    transactionView->setModel(model->getTransactionTableModel());
+    transactionView->setModel(walletModel->getTransactionTableModel());
 
     // Balloon popup for new transaction
-    connect(model->getTransactionTableModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)),
+    connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)),
             this, SLOT(incomingTransaction(const QModelIndex &, int, int)));
 }
 
@@ -234,14 +247,14 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
 void BitcoinGUI::sendcoinsClicked()
 {
     SendCoinsDialog dlg;
-    dlg.setModel(model);
+    dlg.setModel(walletModel);
     dlg.exec();
 }
 
 void BitcoinGUI::addressbookClicked()
 {
     AddressBookDialog dlg(AddressBookDialog::ForEditing);
-    dlg.setModel(model->getAddressTableModel());
+    dlg.setModel(walletModel->getAddressTableModel());
     dlg.setTab(AddressBookDialog::SendingTab);
     dlg.exec();
 }
@@ -249,7 +262,7 @@ void BitcoinGUI::addressbookClicked()
 void BitcoinGUI::receivingAddressesClicked()
 {
     AddressBookDialog dlg(AddressBookDialog::ForEditing);
-    dlg.setModel(model->getAddressTableModel());
+    dlg.setModel(walletModel->getAddressTableModel());
     dlg.setTab(AddressBookDialog::ReceivingTab);
     dlg.exec();
 }
@@ -257,7 +270,7 @@ void BitcoinGUI::receivingAddressesClicked()
 void BitcoinGUI::optionsClicked()
 {
     OptionsDialog dlg;
-    dlg.setModel(model->getOptionsModel());
+    dlg.setModel(clientModel->getOptionsModel());
     dlg.exec();
 }
 
@@ -270,7 +283,7 @@ void BitcoinGUI::aboutClicked()
 void BitcoinGUI::newAddressClicked()
 {
     EditAddressDialog dlg(EditAddressDialog::NewReceivingAddress);
-    dlg.setModel(model->getAddressTableModel());
+    dlg.setModel(walletModel->getAddressTableModel());
     if(dlg.exec())
     {
         QString newAddress = dlg.saveCurrentRow();
@@ -310,7 +323,7 @@ void BitcoinGUI::setNumConnections(int count)
 
 void BitcoinGUI::setNumBlocks(int count)
 {
-    int total = model->getTotalBlocksEstimate();
+    int total = clientModel->getTotalBlocksEstimate();
     if(count < total)
     {
         progressBarLabel->setVisible(true);
@@ -353,7 +366,7 @@ void BitcoinGUI::changeEvent(QEvent *e)
 {
     if (e->type() == QEvent::WindowStateChange)
     {
-        if(model->getOptionsModel()->getMinimizeToTray())
+        if(clientModel->getOptionsModel()->getMinimizeToTray())
         {
             if (isMinimized())
             {
@@ -371,8 +384,8 @@ void BitcoinGUI::changeEvent(QEvent *e)
 
 void BitcoinGUI::closeEvent(QCloseEvent *event)
 {
-    if(!model->getOptionsModel()->getMinimizeToTray() &&
-       !model->getOptionsModel()->getMinimizeOnClose())
+    if(!clientModel->getOptionsModel()->getMinimizeToTray() &&
+       !clientModel->getOptionsModel()->getMinimizeOnClose())
     {
         qApp->quit();
     }
@@ -400,10 +413,10 @@ void BitcoinGUI::transactionDetails(const QModelIndex& idx)
 
 void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end)
 {
-    TransactionTableModel *ttm = model->getTransactionTableModel();
+    TransactionTableModel *ttm = walletModel->getTransactionTableModel();
     qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent)
                     .data(Qt::EditRole).toULongLong();
-    if(amount>0 && !model->inInitialBlockDownload())
+    if(amount>0 && !clientModel->inInitialBlockDownload())
     {
         // On incoming transaction, make an info balloon
         // Unless the initial block download is in progress, to prevent balloon-spam
index f6241a4..41b665c 100644 (file)
@@ -6,6 +6,7 @@
 
 class TransactionTableModel;
 class ClientModel;
+class WalletModel;
 class TransactionView;
 
 QT_BEGIN_NAMESPACE
@@ -22,7 +23,8 @@ class BitcoinGUI : public QMainWindow
     Q_OBJECT
 public:
     explicit BitcoinGUI(QWidget *parent = 0);
-    void setModel(ClientModel *model);
+    void setClientModel(ClientModel *clientModel);
+    void setWalletModel(WalletModel *walletModel);
     
     /* Transaction table tab indices */
     enum {
@@ -37,7 +39,8 @@ protected:
     void closeEvent(QCloseEvent *event);
 
 private:
-    ClientModel *model;
+    ClientModel *clientModel;
+    WalletModel *walletModel;
 
     QLineEdit *address;
     QLabel *labelBalance;
index b70b71e..125cb91 100644 (file)
@@ -9,8 +9,7 @@
 #include <QTimer>
 
 ClientModel::ClientModel(CWallet *wallet, QObject *parent) :
-    QObject(parent), wallet(wallet), optionsModel(0), addressTableModel(0),
-    transactionTableModel(0)
+    QObject(parent), wallet(wallet), optionsModel(0)
 {
     // Until signal notifications is built into the bitcoin core,
     //  simply update everything after polling using a timer.
@@ -19,13 +18,6 @@ ClientModel::ClientModel(CWallet *wallet, QObject *parent) :
     timer->start(MODEL_UPDATE_DELAY);
 
     optionsModel = new OptionsModel(wallet, this);
-    addressTableModel = new AddressTableModel(wallet, this);
-    transactionTableModel = new TransactionTableModel(wallet, this);
-}
-
-qint64 ClientModel::getBalance() const
-{
-    return wallet->GetBalance();
 }
 
 int ClientModel::getNumConnections() const
@@ -38,86 +30,13 @@ int ClientModel::getNumBlocks() const
     return nBestHeight;
 }
 
-int ClientModel::getNumTransactions() const
-{
-    int numTransactions = 0;
-    CRITICAL_BLOCK(wallet->cs_mapWallet)
-    {
-        numTransactions = wallet->mapWallet.size();
-    }
-    return numTransactions;
-}
-
 void ClientModel::update()
 {
     // Plainly emit all signals for now. To be more efficient this should check
     //   whether the values actually changed first, although it'd be even better if these
     //   were events coming in from the bitcoin core.
-    emit balanceChanged(getBalance());
     emit numConnectionsChanged(getNumConnections());
     emit numBlocksChanged(getNumBlocks());
-    emit numTransactionsChanged(getNumTransactions());
-
-    addressTableModel->update();
-}
-
-ClientModel::StatusCode ClientModel::sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs)
-{
-    uint160 hash160 = 0;
-    bool valid = false;
-
-    if(!AddressToHash160(payTo.toUtf8().constData(), hash160))
-    {
-        return InvalidAddress;
-    }
-
-    if(payAmount <= 0)
-    {
-        return InvalidAmount;
-    }
-
-    if(payAmount > getBalance())
-    {
-        return AmountExceedsBalance;
-    }
-
-    if((payAmount + nTransactionFee) > getBalance())
-    {
-        return AmountWithFeeExceedsBalance;
-    }
-
-    CRITICAL_BLOCK(cs_main)
-    {
-        // Send to bitcoin address
-        CWalletTx wtx;
-        CScript scriptPubKey;
-        scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
-
-        std::string strError = wallet->SendMoney(scriptPubKey, payAmount, wtx, true);
-        if (strError == "")
-        {
-            // OK
-        }
-        else if (strError == "ABORTED")
-        {
-            return Aborted;
-        }
-        else
-        {
-            emit error(tr("Sending..."), QString::fromStdString(strError));
-            return MiscError;
-        }
-    }
-
-    // Add addresses that we've sent to to the address book
-    std::string strAddress = payTo.toStdString();
-    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
-    {
-        if (!wallet->mapAddressBook.count(strAddress))
-            wallet->SetAddressBookName(strAddress, addToAddressBookAs.toStdString());
-    }
-
-    return OK;
 }
 
 bool ClientModel::inInitialBlockDownload() const
@@ -130,18 +49,8 @@ int ClientModel::getTotalBlocksEstimate() const
     return GetTotalBlocksEstimate();
 }
 
-
 OptionsModel *ClientModel::getOptionsModel()
 {
     return optionsModel;
 }
 
-AddressTableModel *ClientModel::getAddressTableModel()
-{
-    return addressTableModel;
-}
-
-TransactionTableModel *ClientModel::getTransactionTableModel()
-{
-    return transactionTableModel;
-}
index 9c23a14..a5028ff 100644 (file)
@@ -8,52 +8,35 @@ class AddressTableModel;
 class TransactionTableModel;
 class CWallet;
 
+// Interface to Bitcoin network client
 class ClientModel : public QObject
 {
     Q_OBJECT
 public:
+    // The only reason that this constructor takes a wallet is because
+    // the global client settings are stored in the main wallet.
     explicit ClientModel(CWallet *wallet, QObject *parent = 0);
 
-    enum StatusCode
-    {
-        OK,
-        InvalidAmount,
-        InvalidAddress,
-        AmountExceedsBalance,
-        AmountWithFeeExceedsBalance,
-        Aborted,
-        MiscError
-    };
-
     OptionsModel *getOptionsModel();
-    AddressTableModel *getAddressTableModel();
-    TransactionTableModel *getTransactionTableModel();
 
-    qint64 getBalance() const;
     int getNumConnections() const;
     int getNumBlocks() const;
-    int getNumTransactions() const;
 
-    /* Return true if core is doing initial block download */
+    // Return true if core is doing initial block download
     bool inInitialBlockDownload() const;
-    /* Return conservative estimate of total number of blocks, or 0 if unknown */
+    // Return conservative estimate of total number of blocks, or 0 if unknown
     int getTotalBlocksEstimate() const;
 
-    /* Send coins */
-    StatusCode sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs=QString());
 private:
     CWallet *wallet;
 
     OptionsModel *optionsModel;
-    AddressTableModel *addressTableModel;
-    TransactionTableModel *transactionTableModel;
 
 signals:
-    void balanceChanged(qint64 balance);
     void numConnectionsChanged(int count);
     void numBlocksChanged(int count);
-    void numTransactionsChanged(int count);
-    /* Asynchronous error notification */
+
+    // Asynchronous error notification
     void error(const QString &title, const QString &message);
 
 public slots:
index d83962d..5c889b2 100644 (file)
@@ -1,6 +1,6 @@
 #include "sendcoinsdialog.h"
 #include "ui_sendcoinsdialog.h"
-#include "clientmodel.h"
+#include "walletmodel.h"
 #include "guiutil.h"
 
 #include "addressbookdialog.h"
@@ -29,7 +29,7 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent, const QString &address) :
     }
 }
 
-void SendCoinsDialog::setModel(ClientModel *model)
+void SendCoinsDialog::setModel(WalletModel *model)
 {
     this->model = model;
 }
@@ -64,32 +64,32 @@ void SendCoinsDialog::on_sendButton_clicked()
 
     switch(model->sendCoins(ui->payTo->text(), payAmountParsed, label))
     {
-    case ClientModel::InvalidAddress:
+    case WalletModel::InvalidAddress:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("The recepient address is not valid, please recheck."),
             QMessageBox::Ok, QMessageBox::Ok);
         ui->payTo->setFocus();
         break;
-    case ClientModel::InvalidAmount:
+    case WalletModel::InvalidAmount:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("The amount to pay must be larger than 0."),
             QMessageBox::Ok, QMessageBox::Ok);
         ui->payAmount->setFocus();
         break;
-    case ClientModel::AmountExceedsBalance:
+    case WalletModel::AmountExceedsBalance:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("Amount exceeds your balance"),
             QMessageBox::Ok, QMessageBox::Ok);
         ui->payAmount->setFocus();
         break;
-    case ClientModel::AmountWithFeeExceedsBalance:
+    case WalletModel::AmountWithFeeExceedsBalance:
         QMessageBox::warning(this, tr("Send Coins"),
             tr("Total exceeds your balance when the %1 transaction fee is included").
             arg(GUIUtil::formatMoney(model->getOptionsModel()->getTransactionFee())),
             QMessageBox::Ok, QMessageBox::Ok);
         ui->payAmount->setFocus();
         break;
-    case ClientModel::OK:
+    case WalletModel::OK:
         accept();
         break;
     }
index 206a854..bbb6a5f 100644 (file)
@@ -6,7 +6,7 @@
 namespace Ui {
     class SendCoinsDialog;
 }
-class ClientModel;
+class WalletModel;
 
 class SendCoinsDialog : public QDialog
 {
@@ -16,11 +16,11 @@ public:
     explicit SendCoinsDialog(QWidget *parent = 0, const QString &address = "");
     ~SendCoinsDialog();
 
-    void setModel(ClientModel *model);
+    void setModel(WalletModel *model);
 
 private:
     Ui::SendCoinsDialog *ui;
-    ClientModel *model;
+    WalletModel *model;
 
 private slots:
     void on_addToAddressBook_toggled(bool checked);
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
new file mode 100644 (file)
index 0000000..0fb7d21
--- /dev/null
@@ -0,0 +1,124 @@
+#include "walletmodel.h"
+#include "guiconstants.h"
+#include "optionsmodel.h"
+#include "addresstablemodel.h"
+#include "transactiontablemodel.h"
+
+#include "headers.h"
+
+#include <QTimer>
+
+WalletModel::WalletModel(CWallet *wallet, QObject *parent) :
+    QObject(parent), wallet(wallet), optionsModel(0), addressTableModel(0),
+    transactionTableModel(0)
+{
+    // Until signal notifications is built into the bitcoin core,
+    //  simply update everything after polling using a timer.
+    QTimer *timer = new QTimer(this);
+    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+    timer->start(MODEL_UPDATE_DELAY);
+
+    optionsModel = new OptionsModel(wallet, this);
+    addressTableModel = new AddressTableModel(wallet, this);
+    transactionTableModel = new TransactionTableModel(wallet, this);
+}
+
+qint64 WalletModel::getBalance() const
+{
+    return wallet->GetBalance();
+}
+
+int WalletModel::getNumTransactions() const
+{
+    int numTransactions = 0;
+    CRITICAL_BLOCK(wallet->cs_mapWallet)
+    {
+        numTransactions = wallet->mapWallet.size();
+    }
+    return numTransactions;
+}
+
+void WalletModel::update()
+{
+    // Plainly emit all signals for now. To be more efficient this should check
+    //   whether the values actually changed first, although it'd be even better if these
+    //   were events coming in from the bitcoin core.
+    emit balanceChanged(getBalance());
+    emit numTransactionsChanged(getNumTransactions());
+
+    addressTableModel->update();
+}
+
+WalletModel::StatusCode WalletModel::sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs)
+{
+    uint160 hash160 = 0;
+    bool valid = false;
+
+    if(!AddressToHash160(payTo.toUtf8().constData(), hash160))
+    {
+        return InvalidAddress;
+    }
+
+    if(payAmount <= 0)
+    {
+        return InvalidAmount;
+    }
+
+    if(payAmount > getBalance())
+    {
+        return AmountExceedsBalance;
+    }
+
+    if((payAmount + nTransactionFee) > getBalance())
+    {
+        return AmountWithFeeExceedsBalance;
+    }
+
+    CRITICAL_BLOCK(cs_main)
+    {
+        // Send to bitcoin address
+        CWalletTx wtx;
+        CScript scriptPubKey;
+        scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;
+
+        std::string strError = wallet->SendMoney(scriptPubKey, payAmount, wtx, true);
+        if (strError == "")
+        {
+            // OK
+        }
+        else if (strError == "ABORTED")
+        {
+            return Aborted;
+        }
+        else
+        {
+            emit error(tr("Sending..."), QString::fromStdString(strError));
+            return MiscError;
+        }
+    }
+
+    // Add addresses that we've sent to to the address book
+    std::string strAddress = payTo.toStdString();
+    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
+    {
+        if (!wallet->mapAddressBook.count(strAddress))
+            wallet->SetAddressBookName(strAddress, addToAddressBookAs.toStdString());
+    }
+
+    return OK;
+}
+
+OptionsModel *WalletModel::getOptionsModel()
+{
+    return optionsModel;
+}
+
+AddressTableModel *WalletModel::getAddressTableModel()
+{
+    return addressTableModel;
+}
+
+TransactionTableModel *WalletModel::getTransactionTableModel()
+{
+    return transactionTableModel;
+}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
new file mode 100644 (file)
index 0000000..5b46dfb
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef WALLETMODEL_H
+#define WALLETMODEL_H
+
+#include <QObject>
+
+class OptionsModel;
+class AddressTableModel;
+class TransactionTableModel;
+class CWallet;
+
+// Interface to a Bitcoin wallet
+class WalletModel : public QObject
+{
+    Q_OBJECT
+public:
+    explicit WalletModel(CWallet *wallet, QObject *parent = 0);
+
+    enum StatusCode
+    {
+        OK,
+        InvalidAmount,
+        InvalidAddress,
+        AmountExceedsBalance,
+        AmountWithFeeExceedsBalance,
+        Aborted,
+        MiscError
+    };
+
+    OptionsModel *getOptionsModel();
+    AddressTableModel *getAddressTableModel();
+    TransactionTableModel *getTransactionTableModel();
+
+    qint64 getBalance() const;
+    int getNumTransactions() const;
+
+    /* Send coins */
+    StatusCode sendCoins(const QString &payTo, qint64 payAmount, const QString &addToAddressBookAs=QString());
+private:
+    CWallet *wallet;
+
+    // Wallet has an options model for wallet-specific options
+    // (transaction fee, for example)
+    OptionsModel *optionsModel;
+
+    AddressTableModel *addressTableModel;
+    TransactionTableModel *transactionTableModel;
+
+signals:
+    void balanceChanged(qint64 balance);
+    void numTransactionsChanged(int count);
+
+    // Asynchronous error notification
+    void error(const QString &title, const QString &message);
+
+public slots:
+
+private slots:
+    void update();
+};
+
+
+#endif // WALLETMODEL_H