diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -7,6 +7,7 @@
 
 #include <amount.h>                    // For Amount
 #include <primitives/transaction.h>    // For CTxOut
+#include <pubkey.h>                    // For CTxDestination (CKeyID and CScriptID)
 #include <script/ismine.h>             // For isminefilter, isminetype
 #include <script/standard.h>           // For CTxDestination
 #include <support/allocators/secure.h> // For SecureString
@@ -36,6 +37,7 @@
 
 class Handler;
 class PendingWalletTx;
+struct WalletAddress;
 struct WalletBalances;
 struct WalletTxOut;
 
@@ -76,6 +78,9 @@
     //! Get chainparams.
     virtual const CChainParams &getChainParams() = 0;
 
+    // Get key from pool.
+    virtual bool getKeyFromPool(bool internal, CPubKey &pub_key) = 0;
+
     //! Get public key.
     virtual bool getPubKey(const CKeyID &address, CPubKey &pub_key) = 0;
 
@@ -93,11 +98,17 @@
                                 const std::string &name,
                                 const std::string &purpose) = 0;
 
+    // Remove address.
+    virtual bool delAddressBook(const CTxDestination &dest) = 0;
+
     //! Look up address in wallet, return whether exists.
     virtual bool getAddress(const CTxDestination &dest,
                             std::string *name = nullptr,
                             isminetype *is_mine = nullptr) = 0;
 
+    //! Get wallet address list.
+    virtual std::vector<WalletAddress> getAddresses() = 0;
+
     //! Add dest data.
     virtual bool addDestData(const CTxDestination &dest, const std::string &key,
                              const std::string &value) = 0;
@@ -204,6 +215,19 @@
                         std::string &reject_reason) = 0;
 };
 
+//! Information about one wallet address.
+struct WalletAddress {
+    CTxDestination dest;
+    isminetype is_mine;
+    std::string name;
+    std::string purpose;
+
+    WalletAddress(CTxDestination destIn, isminetype isMineIn,
+                  std::string nameIn, std::string purposeIn)
+        : dest(std::move(destIn)), is_mine(isMineIn), name(std::move(nameIn)),
+          purpose(std::move(purposeIn)) {}
+};
+
 //! Collection of wallet balances.
 struct WalletBalances {
     Amount balance = Amount::zero();
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -84,6 +84,9 @@
             return m_wallet.BackupWallet(filename);
         }
         std::string getWalletName() override { return m_wallet.GetName(); }
+        bool getKeyFromPool(bool internal, CPubKey &pub_key) override {
+            return m_wallet.GetKeyFromPool(pub_key, internal);
+        }
         const CChainParams &getChainParams() override {
             return m_wallet.chainParams;
         }
@@ -101,6 +104,9 @@
                             const std::string &purpose) override {
             return m_wallet.SetAddressBook(dest, name, purpose);
         }
+        bool delAddressBook(const CTxDestination &dest) override {
+            return m_wallet.DelAddressBook(dest);
+        }
         bool getAddress(const CTxDestination &dest, std::string *name,
                         isminetype *is_mine) override {
             LOCK(m_wallet.cs_wallet);
@@ -116,6 +122,15 @@
             }
             return true;
         }
+        std::vector<WalletAddress> getAddresses() override {
+            LOCK(m_wallet.cs_wallet);
+            std::vector<WalletAddress> result;
+            for (const auto &item : m_wallet.mapAddressBook) {
+                result.emplace_back(item.first, IsMine(m_wallet, item.first),
+                                    item.second.name, item.second.purpose);
+            }
+            return result;
+        }
         bool addDestData(const CTxDestination &dest, const std::string &key,
                          const std::string &value) override {
             LOCK(m_wallet.cs_wallet);
diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -11,7 +11,9 @@
 class AddressTablePriv;
 class WalletModel;
 
-class CWallet;
+namespace interfaces {
+class Wallet;
+}
 
 /**
  * Qt model of the address book in the core. This allows views to access and
@@ -21,7 +23,7 @@
     Q_OBJECT
 
 public:
-    explicit AddressTableModel(CWallet *wallet, WalletModel *parent = 0);
+    explicit AddressTableModel(WalletModel *parent = 0);
     ~AddressTableModel();
 
     enum ColumnIndex {
@@ -93,7 +95,6 @@
 
 private:
     WalletModel *walletModel;
-    CWallet *wallet;
     AddressTablePriv *priv;
     QStringList columns;
     EditStatus editStatus;
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -2,13 +2,13 @@
 // Distributed under the MIT software license, see the accompanying
 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 
-#include "addresstablemodel.h"
+#include <qt/addresstablemodel.h>
 
-#include "guiutil.h"
-#include "walletmodel.h"
-
-#include "dstencode.h"
-#include "wallet/wallet.h"
+#include <dstencode.h>
+#include <interfaces/node.h>
+#include <qt/guiutil.h>
+#include <qt/walletmodel.h>
+#include <wallet/wallet.h>
 
 #include <QDebug>
 #include <QFont>
@@ -68,28 +68,19 @@
 // Private implementation
 class AddressTablePriv {
 public:
-    CWallet *wallet;
     QList<AddressTableEntry> cachedAddressTable;
     AddressTableModel *parent;
 
-    AddressTablePriv(CWallet *_wallet, AddressTableModel *_parent)
-        : wallet(_wallet), parent(_parent) {}
+    AddressTablePriv(AddressTableModel *_parent) : parent(_parent) {}
 
-    void refreshAddressTable() {
+    void refreshAddressTable(interfaces::Wallet &wallet) {
         cachedAddressTable.clear();
-        {
-            LOCK(wallet->cs_wallet);
-            for (const std::pair<CTxDestination, CAddressBookData> &item :
-                 wallet->mapAddressBook) {
-                const CTxDestination &address = item.first;
-                bool fMine = IsMine(*wallet, address);
-                AddressTableEntry::Type addressType = translateTransactionType(
-                    QString::fromStdString(item.second.purpose), fMine);
-                const std::string &strName = item.second.name;
-                cachedAddressTable.append(AddressTableEntry(
-                    addressType, QString::fromStdString(strName),
-                    QString::fromStdString(EncodeDestination(address))));
-            }
+        for (const auto &address : wallet.getAddresses()) {
+            AddressTableEntry::Type addressType = translateTransactionType(
+                QString::fromStdString(address.purpose), address.is_mine);
+            cachedAddressTable.append(AddressTableEntry(
+                addressType, QString::fromStdString(address.name),
+                QString::fromStdString(EncodeDestination(address.dest))));
         }
         // qLowerBound() and qUpperBound() require our cachedAddressTable list
         // to be sorted in asc order. Even though the map is already sorted this
@@ -162,12 +153,11 @@
     }
 };
 
-AddressTableModel::AddressTableModel(CWallet *_wallet, WalletModel *parent)
-    : QAbstractTableModel(parent), walletModel(parent), wallet(_wallet),
-      priv(0) {
+AddressTableModel::AddressTableModel(WalletModel *parent)
+    : QAbstractTableModel(parent), walletModel(parent), priv(0) {
     columns << tr("Label") << tr("Address");
-    priv = new AddressTablePriv(wallet, this);
-    priv->refreshAddressTable();
+    priv = new AddressTablePriv(this);
+    priv->refreshAddressTable(parent->wallet());
 }
 
 AddressTableModel::~AddressTableModel() {
@@ -230,20 +220,19 @@
     editStatus = OK;
 
     if (role == Qt::EditRole) {
-        LOCK(wallet->cs_wallet); /* For SetAddressBook / DelAddressBook */
-        CTxDestination curAddress =
-            DecodeDestination(rec->address.toStdString(), wallet->chainParams);
+        CTxDestination curAddress = DecodeDestination(
+            rec->address.toStdString(), walletModel->getChainParams());
         if (index.column() == Label) {
             // Do nothing, if old label == new label
             if (rec->label == value.toString()) {
                 editStatus = NO_CHANGES;
                 return false;
             }
-            wallet->SetAddressBook(curAddress, value.toString().toStdString(),
-                                   strPurpose);
+            walletModel->wallet().setAddressBook(
+                curAddress, value.toString().toStdString(), strPurpose);
         } else if (index.column() == Address) {
             CTxDestination newAddress = DecodeDestination(
-                value.toString().toStdString(), wallet->chainParams);
+                value.toString().toStdString(), walletModel->getChainParams());
             // Refuse to set invalid address, set error status and return false
             if (boost::get<CNoDestination>(&newAddress)) {
                 editStatus = INVALID_ADDRESS;
@@ -257,17 +246,17 @@
             // Check for duplicate addresses to prevent accidental deletion of
             // addresses, if you try to paste an existing address over another
             // address (with a different label)
-            else if (wallet->mapAddressBook.count(newAddress)) {
+            if (walletModel->wallet().getAddress(newAddress)) {
                 editStatus = DUPLICATE_ADDRESS;
                 return false;
             }
             // Double-check that we're not overwriting a receiving address
             else if (rec->type == AddressTableEntry::Sending) {
                 // Remove old entry
-                wallet->DelAddressBook(curAddress);
+                walletModel->wallet().delAddressBook(curAddress);
                 // Add new entry with new address
-                wallet->SetAddressBook(newAddress, rec->label.toStdString(),
-                                       strPurpose);
+                walletModel->wallet().setAddressBook(
+                    newAddress, value.toString().toStdString(), strPurpose);
             }
         }
         return true;
@@ -332,25 +321,24 @@
             return QString();
         }
         // Check for duplicate addresses
-        {
-            LOCK(wallet->cs_wallet);
-            if (wallet->mapAddressBook.count(
-                    DecodeDestination(strAddress, wallet->chainParams))) {
-                editStatus = DUPLICATE_ADDRESS;
-                return QString();
-            }
+        if (walletModel->wallet().getAddress(
+                DecodeDestination(strAddress, walletModel->getChainParams()))) {
+            editStatus = DUPLICATE_ADDRESS;
+            return QString();
         }
     } else if (type == Receive) {
         // Generate a new address to associate with given label
         CPubKey newKey;
-        if (!wallet->GetKeyFromPool(newKey)) {
+        if (!walletModel->wallet().getKeyFromPool(false /* internal */,
+                                                  newKey)) {
             WalletModel::UnlockContext ctx(walletModel->requestUnlock());
             if (!ctx.isValid()) {
                 // Unlock wallet failed or was cancelled
                 editStatus = WALLET_UNLOCK_FAILURE;
                 return QString();
             }
-            if (!wallet->GetKeyFromPool(newKey)) {
+            if (!walletModel->wallet().getKeyFromPool(false /* internal */,
+                                                      newKey)) {
                 editStatus = KEY_GENERATION_FAILURE;
                 return QString();
             }
@@ -361,8 +349,9 @@
     }
 
     // Add entry
-    wallet->SetAddressBook(DecodeDestination(strAddress, wallet->chainParams),
-                           strLabel, (type == Send ? "send" : "receive"));
+    walletModel->wallet().setAddressBook(
+        DecodeDestination(strAddress, walletModel->getChainParams()), strLabel,
+        (type == Send ? "send" : "receive"));
     return QString::fromStdString(strAddress);
 }
 
@@ -376,23 +365,19 @@
         // Also refuse to remove receiving addresses.
         return false;
     }
-    wallet->DelAddressBook(
-        DecodeDestination(rec->address.toStdString(), wallet->chainParams));
+    walletModel->wallet().delAddressBook(DecodeDestination(
+        rec->address.toStdString(), walletModel->getChainParams()));
     return true;
 }
 
 /* Look up label for address in address book, if not found return empty string.
  */
 QString AddressTableModel::labelForAddress(const QString &address) const {
-    {
-        LOCK(wallet->cs_wallet);
-        CTxDestination destination =
-            DecodeDestination(address.toStdString(), wallet->chainParams);
-        std::map<CTxDestination, CAddressBookData>::iterator mi =
-            wallet->mapAddressBook.find(destination);
-        if (mi != wallet->mapAddressBook.end()) {
-            return QString::fromStdString(mi->second.name);
-        }
+    CTxDestination destination =
+        DecodeDestination(address.toStdString(), walletModel->getChainParams());
+    std::string name;
+    if (walletModel->wallet().getAddress(destination, &name)) {
+        return QString::fromStdString(name);
     }
     return QString();
 }
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -43,7 +43,7 @@
     fHaveWatchOnly = m_wallet->haveWatchOnly();
     fForceCheckBalanceChanged = false;
 
-    addressTableModel = new AddressTableModel(cwallet, this);
+    addressTableModel = new AddressTableModel(this);
     transactionTableModel =
         new TransactionTableModel(platformStyle, cwallet, this);
     recentRequestsTableModel = new RecentRequestsTableModel(cwallet, this);