diff --git a/core/src/main/java/haveno/core/xmr/model/XmrAddressEntry.java b/core/src/main/java/haveno/core/xmr/model/XmrAddressEntry.java
index 9f64a2efe8..106dbbd807 100644
--- a/core/src/main/java/haveno/core/xmr/model/XmrAddressEntry.java
+++ b/core/src/main/java/haveno/core/xmr/model/XmrAddressEntry.java
@@ -43,7 +43,8 @@ public final class XmrAddressEntry implements PersistablePayload {
         OFFER_FUNDING,
         RESERVED_FOR_TRADE,
         MULTI_SIG,
-        TRADE_PAYOUT
+        TRADE_PAYOUT,
+        BASE_ADDRESS
     }
 
     // keyPair can be null in case the object is created from deserialization as it is transient.
diff --git a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java
index 6c864adb25..95d5866c3d 100644
--- a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java
+++ b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java
@@ -39,6 +39,7 @@ import monero.wallet.MoneroWallet;
 import monero.wallet.MoneroWalletRpc;
 import monero.wallet.model.MoneroCheckTx;
 import monero.wallet.model.MoneroDestination;
+import monero.wallet.model.MoneroIncomingTransfer;
 import monero.wallet.model.MoneroOutputQuery;
 import monero.wallet.model.MoneroOutputWallet;
 import monero.wallet.model.MoneroSubaddress;
@@ -488,7 +489,7 @@ public class XmrWalletService {
                     daemon.flushTxPool(txHash); // flush tx from pool
                 } catch (MoneroRpcError err) {
                     System.out.println(daemon.getRpcConnection());
-                    throw err.getCode() == -32601 ? new RuntimeException("Failed to flush tx from pool. Arbitrator must use trusted, unrestricted daemon") : err;
+                    throw err.getCode().equals(-32601) ? new RuntimeException("Failed to flush tx from pool. Arbitrator must use trusted, unrestricted daemon") : err;
                 }
             }
             return new Tuple2<>(tx, actualSecurityDeposit);
@@ -838,24 +839,29 @@ public class XmrWalletService {
     // ----------------------------- LEGACY APP -------------------------------
 
     public synchronized XmrAddressEntry getNewAddressEntry() {
-        return getNewAddressEntry(XmrAddressEntry.Context.AVAILABLE);
+        return getNewAddressEntryAux(null, XmrAddressEntry.Context.AVAILABLE);
     }
 
     public synchronized XmrAddressEntry getNewAddressEntry(String offerId, XmrAddressEntry.Context context) {
 
         // try to use available and not yet used entries
         try {
-            List<MoneroTxWallet> incomingTxs = getIncomingTxs(); // prefetch all incoming txs to avoid query per subaddress
+            List<MoneroTxWallet> incomingTxs = getTxsWithIncomingOutputs(); // prefetch all incoming txs to avoid query per subaddress
             Optional<XmrAddressEntry> emptyAvailableAddressEntry = getAddressEntryListAsImmutableList().stream().filter(e -> XmrAddressEntry.Context.AVAILABLE == e.getContext()).filter(e -> isSubaddressUnused(e.getSubaddressIndex(), incomingTxs)).findAny();
             if (emptyAvailableAddressEntry.isPresent()) return xmrAddressEntryList.swapAvailableToAddressEntryWithOfferId(emptyAvailableAddressEntry.get(), context, offerId);
         } catch (Exception e) {
-            log.warn("Error getting new address entriy based on incoming transactions");
+            log.warn("Error getting new address entry based on incoming transactions");
             e.printStackTrace();
         }
         
-        // create new subaddress and entry
+        // create new entry
+        return getNewAddressEntryAux(offerId, context);
+    }
+
+    private XmrAddressEntry getNewAddressEntryAux(String offerId, XmrAddressEntry.Context context) {
         MoneroSubaddress subaddress = wallet.createSubaddress(0);
         XmrAddressEntry entry = new XmrAddressEntry(subaddress.getIndex(), subaddress.getAddress(), context, offerId, null);
+        log.info("Add new XmrAddressEntry {}", entry);
         xmrAddressEntryList.addAddressEntry(entry);
         return entry;
     }
@@ -866,6 +872,12 @@ public class XmrWalletService {
         else return unusedAddressEntries.get(0);
     }
 
+    public synchronized XmrAddressEntry getFreshAddressEntry(List<MoneroTxWallet> cachedTxs) {
+        List<XmrAddressEntry> unusedAddressEntries = getUnusedAddressEntries(cachedTxs);
+        if (unusedAddressEntries.isEmpty()) return getNewAddressEntry();
+        else return unusedAddressEntries.get(0);
+    }
+
     public synchronized XmrAddressEntry recoverAddressEntry(String offerId, String address, XmrAddressEntry.Context context) {
         var available = findAddressEntry(address, XmrAddressEntry.Context.AVAILABLE);
         if (!available.isPresent()) return null;
@@ -883,7 +895,7 @@ public class XmrWalletService {
         Optional<XmrAddressEntry> addressEntry = getAddressEntryListAsImmutableList().stream()
                 .filter(e -> context == e.getContext())
                 .findAny();
-        return addressEntry.isPresent() ? addressEntry.get() : getNewAddressEntry(context);
+        return addressEntry.isPresent() ? addressEntry.get() : getNewAddressEntryAux(null, context);
     }
 
     public synchronized Optional<XmrAddressEntry> getAddressEntry(String offerId, XmrAddressEntry.Context context) {
@@ -923,14 +935,6 @@ public class XmrWalletService {
         swapTradeEntryToAvailableEntry(offerId, XmrAddressEntry.Context.TRADE_PAYOUT);
     }
 
-    private XmrAddressEntry getNewAddressEntry(XmrAddressEntry.Context context) {
-        MoneroSubaddress subaddress = wallet.createSubaddress(0);
-        XmrAddressEntry entry = new XmrAddressEntry(subaddress.getIndex(), subaddress.getAddress(), context, null, null);
-        log.info("getOrCreateAddressEntry: add new XmrAddressEntry {}", entry);
-        xmrAddressEntryList.addAddressEntry(entry);
-        return entry;
-    }
-
     private Optional<XmrAddressEntry> findAddressEntry(String address, XmrAddressEntry.Context context) {
         return getAddressEntryListAsImmutableList().stream().filter(e -> address.equals(e.getAddressString())).filter(e -> context == e.getContext()).findAny();
     }
@@ -961,13 +965,25 @@ public class XmrWalletService {
     }
 
     public List<XmrAddressEntry> getAddressEntryListAsImmutableList() {
+        List<MoneroSubaddress> subaddresses = wallet.getSubaddresses(0);
+        for (MoneroSubaddress subaddress : subaddresses) {
+            boolean exists = xmrAddressEntryList.getAddressEntriesAsListImmutable().stream().filter(addressEntry -> addressEntry.getAddressString().equals(subaddress.getAddress())).findAny().isPresent();
+            if (!exists) {
+                XmrAddressEntry entry = new XmrAddressEntry(subaddress.getIndex(), subaddress.getAddress(), subaddress.getIndex() == 0 ? XmrAddressEntry.Context.BASE_ADDRESS : XmrAddressEntry.Context.AVAILABLE, null, null);
+                log.info("Add XmrAddressEntry from existing subaddress: {}", entry);
+                xmrAddressEntryList.addAddressEntry(entry);
+            }
+        }
         return xmrAddressEntryList.getAddressEntriesAsListImmutable();
     }
 
     public List<XmrAddressEntry> getUnusedAddressEntries() {
-        List<MoneroTxWallet> incomingTxs = getIncomingTxs(); // prefetch all incoming txs to avoid query per subaddress
+        return getUnusedAddressEntries(getTxsWithIncomingOutputs());
+    }
+
+    public List<XmrAddressEntry> getUnusedAddressEntries(List<MoneroTxWallet> cachedTxs) {
         return getAvailableAddressEntries().stream()
-                .filter(e -> isSubaddressUnused(e.getSubaddressIndex(), incomingTxs))
+                .filter(e -> isSubaddressUnused(e.getSubaddressIndex(), cachedTxs))
                 .collect(Collectors.toList());
     }
 
@@ -976,34 +992,55 @@ public class XmrWalletService {
     }
 
     private boolean isSubaddressUnused(int subaddressIndex, List<MoneroTxWallet> incomingTxs) {
-        return getNumTxOutputsForSubaddress(subaddressIndex, incomingTxs) == 0;
+        return getNumOutputsForSubaddress(subaddressIndex, incomingTxs) == 0;
     }
 
-    public int getNumTxOutputsForSubaddress(int subaddressIndex) {
-        return getNumTxOutputsForSubaddress(subaddressIndex, null);
+    public int getNumOutputsForSubaddress(int subaddressIndex) {
+        return getNumOutputsForSubaddress(subaddressIndex, null);
     }
 
-    public int getNumTxOutputsForSubaddress(int subaddressIndex, List<MoneroTxWallet> incomingTxs) {
-        if (incomingTxs == null) incomingTxs = getIncomingTxs(subaddressIndex);
+    public int getNumOutputsForSubaddress(int subaddressIndex, List<MoneroTxWallet> incomingTxs) {
+        if (incomingTxs == null) incomingTxs = getTxsWithIncomingOutputs(subaddressIndex);
         int numUnspentOutputs = 0;
         for (MoneroTxWallet tx : incomingTxs) {
             if (tx.getTransfers(new MoneroTransferQuery().setSubaddressIndex(subaddressIndex)).isEmpty()) continue;
-            numUnspentOutputs += tx.isConfirmed() ? tx.getOutputsWallet(new MoneroOutputQuery().setSubaddressIndex(subaddressIndex)).size() : 1; // TODO: monero-project does not provide outputs for unconfirmed txs
+            numUnspentOutputs += tx.isConfirmed() ? tx.getOutputsWallet(new MoneroOutputQuery().setAccountIndex(0).setSubaddressIndex(subaddressIndex)).size() : 1; // TODO: monero-project does not provide outputs for unconfirmed txs
         }
         return numUnspentOutputs;
     }
 
-    public List<MoneroTxWallet> getIncomingTxs() {
-        return getIncomingTxs(null);
+    public List<MoneroTxWallet> getTxsWithIncomingOutputs() {
+        return getTxsWithIncomingOutputs(null);
     }
 
-    public List<MoneroTxWallet> getIncomingTxs(Integer subaddressIndex) {
-        return wallet.getTxs(new MoneroTxQuery()
-                .setTransferQuery((new MoneroTransferQuery()
-                        .setAccountIndex(0)
-                        .setSubaddressIndex(subaddressIndex)
-                        .setIsIncoming(true)))
-                .setIncludeOutputs(true));
+    public List<MoneroTxWallet> getTxsWithIncomingOutputs(Integer subaddressIndex) {
+        List<MoneroTxWallet> txs = wallet.getTxs(new MoneroTxQuery().setIncludeOutputs(true));
+        return getTxsWithIncomingOutputs(txs, subaddressIndex);
+    }
+
+    public static List<MoneroTxWallet> getTxsWithIncomingOutputs(List<MoneroTxWallet> txs, Integer subaddressIndex) {
+        List<MoneroTxWallet> incomingTxs = new ArrayList<>();
+        for (MoneroTxWallet tx : txs) {
+            boolean isIncoming = false;
+            if (tx.getIncomingTransfers() != null) {
+                for (MoneroIncomingTransfer transfer : tx.getIncomingTransfers()) {
+                    if (transfer.getAccountIndex().equals(0) && (subaddressIndex == null || transfer.getSubaddressIndex().equals(subaddressIndex))) {
+                        isIncoming = true;
+                        break;
+                    }
+                }
+            }
+            if (tx.getOutputs() != null && !isIncoming) {
+                for (MoneroOutputWallet output : tx.getOutputsWallet()) {
+                    if (output.getAccountIndex().equals(0) && (subaddressIndex == null || output.getSubaddressIndex().equals(subaddressIndex))) {
+                        isIncoming = true;
+                        break;
+                    }
+                }
+            }
+            if (isIncoming) incomingTxs.add(tx);
+        }
+        return incomingTxs;
     }
 
     public BigInteger getBalanceForAddress(String address) {
diff --git a/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositListItem.java b/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositListItem.java
index c4c9036c35..249ebac4b5 100644
--- a/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositListItem.java
+++ b/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositListItem.java
@@ -20,7 +20,6 @@ package haveno.desktop.main.funds.deposit;
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
 
-import common.types.Filter;
 import haveno.core.locale.Res;
 import haveno.core.trade.HavenoUtils;
 import haveno.core.util.coin.CoinFormatter;
@@ -34,8 +33,6 @@ import javafx.beans.property.StringProperty;
 import javafx.scene.control.Tooltip;
 import lombok.extern.slf4j.Slf4j;
 import monero.daemon.model.MoneroTx;
-import monero.wallet.model.MoneroTransferQuery;
-import monero.wallet.model.MoneroTxQuery;
 import monero.wallet.model.MoneroTxWallet;
 
 import java.math.BigInteger;
@@ -49,7 +46,7 @@ class DepositListItem {
     private BigInteger balanceAsBI;
     private String usage = "-";
     private XmrBalanceListener balanceListener;
-    private int numTxOutputs = 0;
+    private int numTxsWithOutputs = 0;
     private final Supplier<LazyFields> lazyFieldsSupplier;
 
     private static class LazyFields {
@@ -98,8 +95,8 @@ class DepositListItem {
     }
 
     private void updateUsage(int subaddressIndex, List<MoneroTxWallet> cachedTxs) {
-        numTxOutputs = xmrWalletService.getNumTxOutputsForSubaddress(addressEntry.getSubaddressIndex(), cachedTxs);
-        usage = numTxOutputs == 0 ? Res.get("funds.deposit.unused") : Res.get("funds.deposit.usedInTx", numTxOutputs);
+        numTxsWithOutputs = XmrWalletService.getTxsWithIncomingOutputs(cachedTxs, addressEntry.getSubaddressIndex()).size();
+        usage = subaddressIndex == 0 ? "Base address" : numTxsWithOutputs == 0 ? Res.get("funds.deposit.unused") : Res.get("funds.deposit.usedInTx", numTxsWithOutputs);
     }
 
     public void cleanup() {
@@ -114,6 +111,10 @@ class DepositListItem {
         return addressEntry.getAddressString();
     }
 
+    public int getSubaddressIndex() {
+        return addressEntry.getSubaddressIndex();
+    }
+
     public String getUsage() {
         return usage;
     }
@@ -130,8 +131,8 @@ class DepositListItem {
         return balanceAsBI;
     }
 
-    public int getNumTxOutputs() {
-        return numTxOutputs;
+    public int getNumTxsWithOutputs() {
+        return numTxsWithOutputs;
     }
 
     public long getNumConfirmationsSinceFirstUsed(List<MoneroTxWallet> incomingTxs) {
@@ -139,14 +140,10 @@ class DepositListItem {
         return tx == null ? 0 : tx.getNumConfirmations();
     }
 
-    private MoneroTxWallet getTxWithFewestConfirmations(List<MoneroTxWallet> incomingTxs) {
+    private MoneroTxWallet getTxWithFewestConfirmations(List<MoneroTxWallet> allIncomingTxs) {
 
-        // get txs with incoming transfers to subaddress
-        MoneroTxQuery query = new MoneroTxQuery()
-                .setTransferQuery(new MoneroTransferQuery()
-                        .setIsIncoming(true)
-                        .setSubaddressIndex(addressEntry.getSubaddressIndex()));
-        List<MoneroTxWallet> txs  = incomingTxs == null ? xmrWalletService.getWallet().getTxs(query) : Filter.apply(query, incomingTxs);
+        // get txs with incoming outputs to subaddress index
+        List<MoneroTxWallet> txs = XmrWalletService.getTxsWithIncomingOutputs(allIncomingTxs, addressEntry.getSubaddressIndex());
         
         // get tx with fewest confirmations
         MoneroTxWallet highestTx = null;
diff --git a/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositView.java b/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositView.java
index b9651b940c..c7f680561f 100644
--- a/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositView.java
+++ b/desktop/src/main/java/haveno/desktop/main/funds/deposit/DepositView.java
@@ -62,6 +62,7 @@ import javafx.scene.layout.VBox;
 import javafx.util.Callback;
 import monero.wallet.model.MoneroTxConfig;
 import monero.wallet.model.MoneroTxWallet;
+import monero.wallet.model.MoneroWalletListener;
 import net.glxn.qrgen.QRCode;
 import net.glxn.qrgen.image.ImageType;
 import org.bitcoinj.core.Coin;
@@ -104,9 +105,11 @@ public class DepositView extends ActivatableView<VBox, Void> {
     private final ObservableList<DepositListItem> observableList = FXCollections.observableArrayList();
     private final SortedList<DepositListItem> sortedList = new SortedList<>(observableList);
     private XmrBalanceListener balanceListener;
+    private MoneroWalletListener walletListener;
     private Subscription amountTextFieldSubscription;
     private ChangeListener<DepositListItem> tableViewSelectionListener;
     private int gridRow = 0;
+    List<MoneroTxWallet> txsWithIncomingOutputs;
 
     ///////////////////////////////////////////////////////////////////////////////////////////
     // Constructor, lifecycle
@@ -130,8 +133,11 @@ public class DepositView extends ActivatableView<VBox, Void> {
         confirmationsColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.confirmations")));
         usageColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.usage")));
 
-        // trigger creation of at least 1 savings address
-        xmrWalletService.getFreshAddressEntry();
+        // prefetch all incoming txs to avoid query per subaddress
+        txsWithIncomingOutputs = xmrWalletService.getTxsWithIncomingOutputs();
+
+        // trigger creation of at least 1 address
+        xmrWalletService.getFreshAddressEntry(txsWithIncomingOutputs);
 
         tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
         tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.deposit.noAddresses")));
@@ -147,13 +153,10 @@ public class DepositView extends ActivatableView<VBox, Void> {
         setUsageColumnCellFactory();
         setConfidenceColumnCellFactory();
 
-        // prefetch all incoming txs to avoid query per subaddress
-        List<MoneroTxWallet> incomingTxs = xmrWalletService.getIncomingTxs();
-
         addressColumn.setComparator(Comparator.comparing(DepositListItem::getAddressString));
         balanceColumn.setComparator(Comparator.comparing(DepositListItem::getBalanceAsBI));
-        confirmationsColumn.setComparator(Comparator.comparingLong(o -> o.getNumConfirmationsSinceFirstUsed(incomingTxs)));
-        usageColumn.setComparator(Comparator.comparingInt(DepositListItem::getNumTxOutputs));
+        confirmationsColumn.setComparator(Comparator.comparingLong(o -> o.getNumConfirmationsSinceFirstUsed(txsWithIncomingOutputs)));
+        usageColumn.setComparator(Comparator.comparingInt(DepositListItem::getNumTxsWithOutputs));
         tableView.getSortOrder().add(usageColumn);
         tableView.setItems(sortedList);
 
@@ -199,7 +202,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
         generateNewAddressButton = buttonCheckBoxHBox.first;
 
         generateNewAddressButton.setOnAction(event -> {
-            boolean hasUnUsedAddress = observableList.stream().anyMatch(e -> e.getNumTxOutputs() == 0);
+            boolean hasUnUsedAddress = observableList.stream().anyMatch(e -> e.getSubaddressIndex() != 0 && xmrWalletService.getTxsWithIncomingOutputs(e.getSubaddressIndex()).isEmpty());
             if (hasUnUsedAddress) {
                 new Popup().warning(Res.get("funds.deposit.selectUnused")).show();
             } else {
@@ -219,6 +222,13 @@ public class DepositView extends ActivatableView<VBox, Void> {
             }
         };
 
+        walletListener = new MoneroWalletListener() {
+            @Override
+            public void onNewBlock(long height) {
+                updateList();
+            }
+        };
+
         GUIUtil.focusWhenAddedToScene(amountTextField);
     }
 
@@ -230,6 +240,8 @@ public class DepositView extends ActivatableView<VBox, Void> {
         updateList();
 
         xmrWalletService.addBalanceListener(balanceListener);
+        xmrWalletService.addWalletListener(walletListener);
+
         amountTextFieldSubscription = EasyBind.subscribe(amountTextField.textProperty(), t -> {
             addressTextField.setAmount(HavenoUtils.parseXmr(t));
             updateQRCode();
@@ -245,6 +257,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
         sortedList.comparatorProperty().unbind();
         observableList.forEach(DepositListItem::cleanup);
         xmrWalletService.removeBalanceListener(balanceListener);
+        xmrWalletService.removeWalletListener(walletListener);
         amountTextFieldSubscription.unsubscribe();
     }
 
@@ -295,9 +308,14 @@ public class DepositView extends ActivatableView<VBox, Void> {
         observableList.forEach(DepositListItem::cleanup);
         observableList.clear();
 
-        List<MoneroTxWallet> incomingTxs = xmrWalletService.getIncomingTxs(); // cache incoming txs for performance
+        // cache incoming txs
+        txsWithIncomingOutputs = xmrWalletService.getTxsWithIncomingOutputs();
+
+        // add available address entries and base address
         xmrWalletService.getAvailableAddressEntries()
-                .forEach(e -> observableList.add(new DepositListItem(e, xmrWalletService, formatter, incomingTxs)));
+                .forEach(e -> observableList.add(new DepositListItem(e, xmrWalletService, formatter, txsWithIncomingOutputs)));
+        xmrWalletService.getAddressEntries(XmrAddressEntry.Context.BASE_ADDRESS)
+                .forEach(e -> observableList.add(new DepositListItem(e, xmrWalletService, formatter, txsWithIncomingOutputs)));
     }
 
     private Coin getAmount() {
diff --git a/proto/src/main/proto/pb.proto b/proto/src/main/proto/pb.proto
index b5bbf530bf..6cfa4c57bd 100644
--- a/proto/src/main/proto/pb.proto
+++ b/proto/src/main/proto/pb.proto
@@ -1308,6 +1308,7 @@ message XmrAddressEntry {
         RESERVED_FOR_TRADE = 4;
         MULTI_SIG = 5;
         TRADE_PAYOUT = 6;
+        BASE_ADDRESS = 7;
     }
 
 	int32 subaddress_index = 7;