diff --git a/core/src/main/java/bisq/core/api/CoreWalletsService.java b/core/src/main/java/bisq/core/api/CoreWalletsService.java
index 5d896670..5378432e 100644
--- a/core/src/main/java/bisq/core/api/CoreWalletsService.java
+++ b/core/src/main/java/bisq/core/api/CoreWalletsService.java
@@ -171,7 +171,7 @@ class CoreWalletsService {
 
     String getXmrNewSubaddress() {
         accountService.checkAccountOpen();
-        return xmrWalletService.getWallet().createSubaddress(0).getAddress();
+        return xmrWalletService.getNewAddressEntry().getAddressString();
     }
 
     List<MoneroTxWallet> getXmrTxs() {
diff --git a/core/src/main/java/bisq/core/btc/listeners/XmrBalanceListener.java b/core/src/main/java/bisq/core/btc/listeners/XmrBalanceListener.java
index 04f20617..8d60825f 100644
--- a/core/src/main/java/bisq/core/btc/listeners/XmrBalanceListener.java
+++ b/core/src/main/java/bisq/core/btc/listeners/XmrBalanceListener.java
@@ -25,8 +25,8 @@ public class XmrBalanceListener {
     public XmrBalanceListener() {
     }
 
-    public XmrBalanceListener(Integer accountIndex) {
-        this.subaddressIndex = accountIndex;
+    public XmrBalanceListener(Integer subaddressIndex) {
+        this.subaddressIndex = subaddressIndex;
     }
 
     public Integer getSubaddressIndex() {
diff --git a/core/src/main/java/bisq/core/btc/wallet/XmrWalletService.java b/core/src/main/java/bisq/core/btc/wallet/XmrWalletService.java
index 14234cfc..993a445c 100644
--- a/core/src/main/java/bisq/core/btc/wallet/XmrWalletService.java
+++ b/core/src/main/java/bisq/core/btc/wallet/XmrWalletService.java
@@ -55,6 +55,7 @@ import monero.wallet.model.MoneroCheckTx;
 import monero.wallet.model.MoneroDestination;
 import monero.wallet.model.MoneroOutputWallet;
 import monero.wallet.model.MoneroSubaddress;
+import monero.wallet.model.MoneroTransferQuery;
 import monero.wallet.model.MoneroTxConfig;
 import monero.wallet.model.MoneroTxQuery;
 import monero.wallet.model.MoneroTxWallet;
@@ -70,6 +71,7 @@ public class XmrWalletService {
 
     // Monero configuration
     // TODO: don't hard code configuration, inject into classes?
+    public static final int NUM_BLOCKS_UNLOCK = 10;
     private static final MoneroNetworkType MONERO_NETWORK_TYPE = getMoneroNetworkType();
     private static final MoneroWalletRpcManager MONERO_WALLET_RPC_MANAGER = new MoneroWalletRpcManager();
     private static final String MONERO_WALLET_RPC_DIR = System.getProperty("user.dir") + File.separator + ".localnet"; // .localnet contains monero-wallet-rpc and wallet files
@@ -634,6 +636,7 @@ public class XmrWalletService {
         // clear wallets
         wallet = null;
         multisigWallets.clear();
+        walletListeners.clear();
     }
     
     private void backupWallet(String walletName) {
@@ -649,7 +652,17 @@ public class XmrWalletService {
     }
     
     // ----------------------------- LEGACY APP -------------------------------
-    
+
+    public XmrAddressEntry getNewAddressEntry() {
+        return getOrCreateAddressEntry(XmrAddressEntry.Context.AVAILABLE, Optional.empty());
+    }
+
+    public XmrAddressEntry getFreshAddressEntry() {
+        List<XmrAddressEntry> unusedAddressEntries = getUnusedAddressEntries();
+        if (unusedAddressEntries.isEmpty()) return getNewAddressEntry();
+        else return unusedAddressEntries.get(0);
+    }
+
     public XmrAddressEntry recoverAddressEntry(String offerId, String address, XmrAddressEntry.Context context) {
         var available = findAddressEntry(address, XmrAddressEntry.Context.AVAILABLE);
         if (!available.isPresent()) return null;
@@ -761,12 +774,21 @@ public class XmrWalletService {
         return xmrAddressEntryList.getAddressEntriesAsListImmutable();
     }
 
-    public boolean isSubaddressUnused(int subaddressIndex) {
-        return subaddressIndex != 0 && getBalanceForSubaddress(subaddressIndex).value == 0;
-        // return !wallet.getSubaddress(accountIndex, 0).isUsed(); // TODO: isUsed()
-        // does not include unconfirmed funds
+    public List<XmrAddressEntry> getUnusedAddressEntries() {
+        return getAvailableAddressEntries().stream()
+                .filter(e -> isSubaddressUnused(e.getSubaddressIndex()))
+                .collect(Collectors.toList());
     }
 
+    public boolean isSubaddressUnused(int subaddressIndex) {
+        return getNumTxOutputsForSubaddress(subaddressIndex) == 0;
+    }
+
+    public Coin getBalanceForAddress(String address) {
+        return getBalanceForSubaddress(wallet.getAddressIndex(address).getIndex());
+    }
+
+    // TODO: Coin represents centineros everywhere, but here it's atomic units. reconcile
     public Coin getBalanceForSubaddress(int subaddressIndex) {
 
         // get subaddress balance
@@ -786,6 +808,24 @@ public class XmrWalletService {
         return Coin.valueOf(balance.longValueExact());
     }
 
+    public int getNumTxOutputsForSubaddress(int subaddressIndex) {
+
+        // get txs with transfers to the subaddress
+        List<MoneroTxWallet> txs = wallet.getTxs(new MoneroTxQuery()
+                .setTransferQuery((new MoneroTransferQuery()
+                        .setAccountIndex(0)
+                        .setSubaddressIndex(subaddressIndex)
+                        .setIsIncoming(true)))
+                .setIncludeOutputs(true));
+
+        // count num outputs
+        int numUnspentOutputs = 0;
+        for (MoneroTxWallet tx : txs) {
+            numUnspentOutputs += tx.isConfirmed() ? tx.getOutputs().size() : 1; // TODO: monero-project does not provide outputs for unconfirmed txs
+        }
+        return numUnspentOutputs;
+    }
+
     public Coin getAvailableConfirmedBalance() {
         return wallet != null ? Coin.valueOf(wallet.getUnlockedBalance(0).longValueExact()) : Coin.ZERO;
     }
diff --git a/core/src/main/java/bisq/core/trade/Trade.java b/core/src/main/java/bisq/core/trade/Trade.java
index c130d5bf..c2b27c43 100644
--- a/core/src/main/java/bisq/core/trade/Trade.java
+++ b/core/src/main/java/bisq/core/trade/Trade.java
@@ -26,7 +26,6 @@ import bisq.core.offer.Offer;
 import bisq.core.offer.OfferDirection;
 import bisq.core.payment.payload.PaymentMethod;
 import bisq.core.proto.CoreProtoResolver;
-import bisq.core.support.dispute.arbitration.arbitrator.Arbitrator;
 import bisq.core.support.dispute.mediation.MediationResultState;
 import bisq.core.support.dispute.refund.RefundResultState;
 import bisq.core.support.messages.ChatMessage;
@@ -886,7 +885,7 @@ public abstract class Trade implements Tradable, Model {
             
             // check if deposit txs unlocked
             if (txs.get(0).isConfirmed() && txs.get(1).isConfirmed()) {
-                long unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + 9;
+                long unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + XmrWalletService.NUM_BLOCKS_UNLOCK - 1;
                 if (havenoWallet.getHeight() >= unlockHeight) {
                     setConfirmedState();
                     return;
@@ -926,7 +925,7 @@ public abstract class Trade implements Tradable, Model {
                 
                 // compute unlock height
                 if (unlockHeight == null && txs.size() == 2 && txs.get(0).isConfirmed() && txs.get(1).isConfirmed()) {
-                    unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + 9;
+                    unlockHeight = Math.max(txs.get(0).getHeight(), txs.get(0).getHeight()) + XmrWalletService.NUM_BLOCKS_UNLOCK - 1;
                 }
                 
                 // check if txs unlocked
diff --git a/core/src/main/java/bisq/core/util/ParsingUtils.java b/core/src/main/java/bisq/core/util/ParsingUtils.java
index de6c8fd2..304f959e 100644
--- a/core/src/main/java/bisq/core/util/ParsingUtils.java
+++ b/core/src/main/java/bisq/core/util/ParsingUtils.java
@@ -25,6 +25,10 @@ public class ParsingUtils {
         return centinerosToAtomicUnits(coin.value);
     }
 
+    public static double coinToXmr(Coin coin) {
+        return atomicUnitsToXmr(coinToAtomicUnits(coin));
+    }
+
     public static BigInteger centinerosToAtomicUnits(long centineros) {
         return BigInteger.valueOf(centineros).multiply(ParsingUtils.CENTINEROS_AU_MULTIPLIER);
     }
@@ -39,7 +43,11 @@ public class ParsingUtils {
 
     public static long atomicUnitsToCentineros(BigInteger atomicUnits) {
         return atomicUnits.divide(CENTINEROS_AU_MULTIPLIER).longValueExact();
-      }
+    }
+
+    public static Coin atomicUnitsToCoin(BigInteger atomicUnits) {
+        return Coin.valueOf(atomicUnitsToCentineros(atomicUnits));
+    }
 
     public static double atomicUnitsToXmr(BigInteger atomicUnits) {
       return new BigDecimal(atomicUnits).divide(new BigDecimal(XMR_AU_MULTIPLIER)).doubleValue();
diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties
index 8d8209ca..ba89e6c2 100644
--- a/core/src/main/resources/i18n/displayStrings.properties
+++ b/core/src/main/resources/i18n/displayStrings.properties
@@ -127,7 +127,7 @@ shared.noDateAvailable=No date available
 shared.noDetailsAvailable=No details available
 shared.notUsedYet=Not used yet
 shared.date=Date
-shared.sendFundsDetailsWithFee=Sending: {0}\nFrom address: {1}\nTo receiving address: {2}.\nRequired mining fee is: {3} ({4} satoshis/vbyte)\nTransaction vsize: {5} vKb\n\nThe recipient will receive: {6}\n\nAre you sure you want to withdraw this amount?
+shared.sendFundsDetailsWithFee=Sending: {0}\nFrom address: {1}\nTo receiving address: {2}.\nRequired mining fee is: {3}\n\nThe recipient will receive: {4}\n\nAre you sure you want to withdraw this amount?
 # suppress inspection "TrailingSpacesInProperty"
 shared.sendFundsDetailsDust=Haveno detected that this transaction would create a change output which is below the minimum dust threshold (and therefore not allowed by Monero consensus rules). Instead, this dust ({0} satoshi{1}) will be added to the mining fee.\n\n\n
 shared.copyToClipboard=Copy to clipboard
diff --git a/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java b/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java
index 90a26a35..73b99b56 100644
--- a/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java
+++ b/desktop/src/main/java/bisq/desktop/components/TxIdTextField.java
@@ -20,19 +20,17 @@ package bisq.desktop.components;
 import bisq.desktop.components.indicator.TxConfidenceIndicator;
 import bisq.desktop.util.GUIUtil;
 
-import bisq.core.btc.listeners.TxConfidenceListener;
-import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Res;
 import bisq.core.user.BlockChainExplorer;
 import bisq.core.user.Preferences;
 
 import bisq.common.util.Utilities;
 
-import org.bitcoinj.core.TransactionConfidence;
 
 import de.jensd.fx.fontawesome.AwesomeDude;
 import de.jensd.fx.fontawesome.AwesomeIcon;
-
+import java.math.BigInteger;
 import com.jfoenix.controls.JFXTextField;
 
 import javafx.scene.control.Label;
@@ -42,21 +40,23 @@ import javafx.scene.layout.AnchorPane;
 
 import lombok.Getter;
 import lombok.Setter;
-
+import monero.wallet.model.MoneroTxWallet;
+import monero.wallet.model.MoneroWalletListener;
 import javax.annotation.Nullable;
 
 public class TxIdTextField extends AnchorPane {
     @Setter
     private static Preferences preferences;
     @Setter
-    private static BtcWalletService walletService;
+    private static XmrWalletService xmrWalletService;
 
     @Getter
     private final TextField textField;
     private final Tooltip progressIndicatorTooltip;
     private final TxConfidenceIndicator txConfidenceIndicator;
     private final Label copyIcon, blockExplorerIcon, missingTxWarningIcon;
-    private TxConfidenceListener txConfidenceListener;
+
+    private MoneroWalletListener txUpdater;
 
     ///////////////////////////////////////////////////////////////////////////////////////////
     // Constructor
@@ -113,8 +113,10 @@ public class TxIdTextField extends AnchorPane {
     }
 
     public void setup(@Nullable String txId) {
-        if (txConfidenceListener != null)
-            walletService.removeTxConfidenceListener(txConfidenceListener);
+        if (txUpdater != null) {
+            xmrWalletService.removeWalletListener(txUpdater);
+            txUpdater = null;
+        }
 
         if (txId == null) {
             textField.setText(Res.get("shared.na"));
@@ -128,15 +130,22 @@ public class TxIdTextField extends AnchorPane {
             missingTxWarningIcon.setManaged(true);
             return;
         }
-
-        txConfidenceListener = new TxConfidenceListener(txId) {
+        
+        // listen for tx updates
+        // TODO: this only listens for new blocks, listen for double spend
+        txUpdater = new MoneroWalletListener() {
             @Override
-            public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
-                updateConfidence(confidence);
+            public void onNewBlock(long height) {
+                updateConfidence(txId);
+            }
+            @Override
+            public void onBalancesChanged(BigInteger newBalance, BigInteger newUnlockedBalance) {
+                updateConfidence(txId);
             }
         };
-        walletService.addTxConfidenceListener(txConfidenceListener);
-        updateConfidence(walletService.getConfidenceForTxId(txId));
+        xmrWalletService.addWalletListener(txUpdater);
+
+        updateConfidence(txId);
 
         textField.setText(txId);
         textField.setOnMouseClicked(mouseEvent -> openBlockExplorer(txId));
@@ -145,9 +154,10 @@ public class TxIdTextField extends AnchorPane {
     }
 
     public void cleanup() {
-        if (walletService != null && txConfidenceListener != null)
-            walletService.removeTxConfidenceListener(txConfidenceListener);
-
+        if (xmrWalletService != null && txUpdater != null) {
+            xmrWalletService.removeWalletListener(txUpdater);
+            txUpdater = null;
+        }
         textField.setOnMouseClicked(null);
         blockExplorerIcon.setOnMouseClicked(null);
         copyIcon.setOnMouseClicked(null);
@@ -165,9 +175,15 @@ public class TxIdTextField extends AnchorPane {
         }
     }
 
-    private void updateConfidence(TransactionConfidence confidence) {
-        GUIUtil.updateConfidence(confidence, progressIndicatorTooltip, txConfidenceIndicator);
-        if (confidence != null) {
+    private void updateConfidence(String txId) {
+        MoneroTxWallet tx = null;
+        try {
+            tx = xmrWalletService.getWallet().getTx(txId);
+        } catch (Exception e) {
+            // do nothing
+        }
+        GUIUtil.updateConfidence(tx, progressIndicatorTooltip, txConfidenceIndicator);
+        if (tx != null) {
             if (txConfidenceIndicator.getProgress() != 0) {
                 txConfidenceIndicator.setVisible(true);
                 AnchorPane.setRightAnchor(txConfidenceIndicator, 0.0);
diff --git a/desktop/src/main/java/bisq/desktop/main/MainView.java b/desktop/src/main/java/bisq/desktop/main/MainView.java
index 8db799fb..1a9345a8 100644
--- a/desktop/src/main/java/bisq/desktop/main/MainView.java
+++ b/desktop/src/main/java/bisq/desktop/main/MainView.java
@@ -200,8 +200,8 @@ public class MainView extends InitializableView<StackPane, MainViewModel>  {
                         sellButton.fire();
                     } else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT4, keyEvent)) {
                         portfolioButton.fire();
-//                    } else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT5, keyEvent)) {
-//                        fundsButton.fire();
+                    } else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT5, keyEvent)) {
+                        fundsButton.fire();
                     } else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT6, keyEvent)) {
                         supportButton.fire();
                     } else if (Utilities.isAltOrCtrlPressed(KeyCode.DIGIT7, keyEvent)) {
@@ -304,7 +304,7 @@ public class MainView extends InitializableView<StackPane, MainViewModel>  {
         });
 
         HBox primaryNav = new HBox(marketButton, getNavigationSeparator(), buyButton, getNavigationSeparator(),
-                sellButton, getNavigationSeparator(), portfolioButtonWithBadge, getNavigationSeparator());
+                sellButton, getNavigationSeparator(), portfolioButtonWithBadge, getNavigationSeparator(), fundsButton);
 
         primaryNav.setAlignment(Pos.CENTER_LEFT);
         primaryNav.getStyleClass().add("nav-primary");
diff --git a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java
index 5d065b6f..d5d4dfd1 100644
--- a/desktop/src/main/java/bisq/desktop/main/MainViewModel.java
+++ b/desktop/src/main/java/bisq/desktop/main/MainViewModel.java
@@ -43,7 +43,7 @@ import bisq.core.alert.PrivateNotificationManager;
 import bisq.core.api.CoreMoneroConnectionsService;
 import bisq.core.app.HavenoSetup;
 import bisq.core.btc.nodes.LocalBitcoinNode;
-import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.CryptoCurrency;
 import bisq.core.locale.CurrencyUtil;
 import bisq.core.locale.Res;
@@ -153,7 +153,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
     @Inject
     public MainViewModel(HavenoSetup bisqSetup,
                          CoreMoneroConnectionsService connectionService,
-                         BtcWalletService btcWalletService,
+                         XmrWalletService xmrWalletService,
                          User user,
                          BalancePresentation balancePresentation,
                          TradePresentation tradePresentation,
@@ -202,7 +202,7 @@ public class MainViewModel implements ViewModel, HavenoSetup.HavenoSetupListener
 
         TxIdTextField.setPreferences(preferences);
 
-        TxIdTextField.setWalletService(btcWalletService);
+        TxIdTextField.setXmrWalletService(xmrWalletService);
 
         GUIUtil.setFeeService(feeService);
         GUIUtil.setPreferences(preferences);
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java
index fa1681c8..97f7f4ce 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositListItem.java
@@ -17,117 +17,60 @@
 
 package bisq.desktop.main.funds.deposit;
 
-import bisq.desktop.components.indicator.TxConfidenceIndicator;
-import bisq.desktop.util.GUIUtil;
-
-import bisq.core.btc.listeners.BalanceListener;
-import bisq.core.btc.listeners.TxConfidenceListener;
-import bisq.core.btc.model.AddressEntry;
-import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.listeners.XmrBalanceListener;
+import bisq.core.btc.model.XmrAddressEntry;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Res;
+import bisq.core.util.ParsingUtils;
 import bisq.core.util.coin.CoinFormatter;
-
-import org.bitcoinj.core.Address;
-import org.bitcoinj.core.Coin;
-import org.bitcoinj.core.Transaction;
-import org.bitcoinj.core.TransactionConfidence;
-
-import com.google.common.base.Suppliers;
-
-import javafx.scene.control.Tooltip;
-
+import java.math.BigInteger;
 import javafx.beans.property.SimpleStringProperty;
 import javafx.beans.property.StringProperty;
-
-import java.util.function.Supplier;
-
 import lombok.extern.slf4j.Slf4j;
+import org.bitcoinj.core.Coin;
 
 @Slf4j
 class DepositListItem {
     private final StringProperty balance = new SimpleStringProperty();
-    private final BtcWalletService walletService;
+    private final XmrAddressEntry addressEntry;
+    private final XmrWalletService xmrWalletService;
     private Coin balanceAsCoin;
-    private final String addressString;
     private String usage = "-";
-    private TxConfidenceListener txConfidenceListener;
-    private BalanceListener balanceListener;
+    private XmrBalanceListener balanceListener;
     private int numTxOutputs = 0;
-    private final Supplier<LazyFields> lazyFieldsSupplier;
 
-    private static class LazyFields {
-        TxConfidenceIndicator txConfidenceIndicator;
-        Tooltip tooltip;
-    }
+    DepositListItem(XmrAddressEntry addressEntry, XmrWalletService xmrWalletService, CoinFormatter formatter) {
+        this.xmrWalletService = xmrWalletService;
+        this.addressEntry = addressEntry;
 
-    private LazyFields lazy() {
-        return lazyFieldsSupplier.get();
-    }
-
-    DepositListItem(AddressEntry addressEntry, BtcWalletService walletService, CoinFormatter formatter) {
-        this.walletService = walletService;
-
-        addressString = addressEntry.getAddressString();
-
-        Address address = addressEntry.getAddress();
-        TransactionConfidence confidence = walletService.getConfidenceForAddress(address);
-
-        // confidence
-        lazyFieldsSupplier = Suppliers.memoize(() -> new LazyFields() {{
-            txConfidenceIndicator = new TxConfidenceIndicator();
-            txConfidenceIndicator.setId("funds-confidence");
-            tooltip = new Tooltip(Res.get("shared.notUsedYet"));
-            txConfidenceIndicator.setProgress(0);
-            txConfidenceIndicator.setTooltip(tooltip);
-            if (confidence != null) {
-                GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator);
-            }
-        }});
-
-        if (confidence != null) {
-            txConfidenceListener = new TxConfidenceListener(confidence.getTransactionHash().toString()) {
-                @Override
-                public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
-                    GUIUtil.updateConfidence(confidence, lazy().tooltip, lazy().txConfidenceIndicator);
-                }
-            };
-            walletService.addTxConfidenceListener(txConfidenceListener);
-        }
-
-        balanceListener = new BalanceListener(address) {
+        balanceListener = new XmrBalanceListener(addressEntry.getSubaddressIndex()) {
             @Override
-            public void onBalanceChanged(Coin balanceAsCoin, Transaction tx) {
-                DepositListItem.this.balanceAsCoin = balanceAsCoin;
+            public void onBalanceChanged(BigInteger balance) {
+                DepositListItem.this.balanceAsCoin = ParsingUtils.atomicUnitsToCoin(balance);
                 DepositListItem.this.balance.set(formatter.formatCoin(balanceAsCoin));
-                var confidence = walletService.getConfidenceForTxId(tx.getTxId().toString());
-                GUIUtil.updateConfidence(confidence, lazy().tooltip, lazy().txConfidenceIndicator);
-                updateUsage(address);
+                updateUsage(addressEntry.getSubaddressIndex());
             }
         };
-        walletService.addBalanceListener(balanceListener);
+        xmrWalletService.addBalanceListener(balanceListener);
 
-        balanceAsCoin = walletService.getBalanceForAddress(address);
+        balanceAsCoin = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex()); // TODO: Coin represents centineros everywhere, but here it's atomic units. reconcile
+        balanceAsCoin = Coin.valueOf(ParsingUtils.atomicUnitsToCentineros(balanceAsCoin.longValue())); // in centineros
         balance.set(formatter.formatCoin(balanceAsCoin));
 
-        updateUsage(address);
+        updateUsage(addressEntry.getSubaddressIndex());
     }
 
-    private void updateUsage(Address address) {
-        numTxOutputs = walletService.getNumTxOutputsForAddress(address);
+    private void updateUsage(int subaddressIndex) {
+        numTxOutputs = xmrWalletService.getNumTxOutputsForSubaddress(addressEntry.getSubaddressIndex());
         usage = numTxOutputs == 0 ? Res.get("funds.deposit.unused") : Res.get("funds.deposit.usedInTx", numTxOutputs);
     }
 
     public void cleanup() {
-        walletService.removeTxConfidenceListener(txConfidenceListener);
-        walletService.removeBalanceListener(balanceListener);
-    }
-
-    public TxConfidenceIndicator getTxConfidenceIndicator() {
-        return lazy().txConfidenceIndicator;
+        xmrWalletService.removeBalanceListener(balanceListener);
     }
 
     public String getAddressString() {
-        return addressString;
+        return addressEntry.getAddressString();
     }
 
     public String getUsage() {
@@ -149,4 +92,8 @@ class DepositListItem {
     public int getNumTxOutputs() {
         return numTxOutputs;
     }
+
+    public int getNumConfirmationsSinceFirstUsed() {
+        throw new RuntimeException("Not implemented");
+    }
 }
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java
index e03dd18d..2352db17 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java
@@ -30,9 +30,9 @@ import bisq.desktop.main.overlays.windows.QRCodeWindow;
 import bisq.desktop.util.GUIUtil;
 import bisq.desktop.util.Layout;
 
-import bisq.core.btc.listeners.BalanceListener;
-import bisq.core.btc.model.AddressEntry;
-import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.listeners.XmrBalanceListener;
+import bisq.core.btc.model.XmrAddressEntry;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Res;
 import bisq.core.user.Preferences;
 import bisq.core.util.FormattingUtils;
@@ -41,21 +41,16 @@ import bisq.core.util.coin.CoinFormatter;
 
 import bisq.common.UserThread;
 import bisq.common.app.DevEnv;
-import bisq.common.config.Config;
 import bisq.common.util.Tuple3;
 
-import org.bitcoinj.core.Address;
 import org.bitcoinj.core.Coin;
-import org.bitcoinj.core.NetworkParameters;
-import org.bitcoinj.core.SegwitAddress;
-import org.bitcoinj.core.Transaction;
 
 import net.glxn.qrgen.QRCode;
 import net.glxn.qrgen.image.ImageType;
 
 import javax.inject.Inject;
 import javax.inject.Named;
-
+import monero.wallet.model.MoneroTxConfig;
 import javafx.fxml.FXML;
 
 import javafx.scene.control.Button;
@@ -85,7 +80,7 @@ import javafx.collections.transformation.SortedList;
 import javafx.util.Callback;
 
 import java.io.ByteArrayInputStream;
-
+import java.math.BigInteger;
 import java.util.Comparator;
 import java.util.concurrent.TimeUnit;
 
@@ -105,17 +100,16 @@ public class DepositView extends ActivatableView<VBox, Void> {
     private ImageView qrCodeImageView;
     private AddressTextField addressTextField;
     private Button generateNewAddressButton;
-    private CheckBox generateNewAddressSegwitCheckbox;
     private TitledGroupBg titledGroupBg;
     private InputTextField amountTextField;
 
-    private final BtcWalletService walletService;
+    private final XmrWalletService xmrWalletService;
     private final Preferences preferences;
     private final CoinFormatter formatter;
     private String paymentLabelString;
     private final ObservableList<DepositListItem> observableList = FXCollections.observableArrayList();
     private final SortedList<DepositListItem> sortedList = new SortedList<>(observableList);
-    private BalanceListener balanceListener;
+    private XmrBalanceListener balanceListener;
     private Subscription amountTextFieldSubscription;
     private ChangeListener<DepositListItem> tableViewSelectionListener;
     private int gridRow = 0;
@@ -125,10 +119,10 @@ public class DepositView extends ActivatableView<VBox, Void> {
     ///////////////////////////////////////////////////////////////////////////////////////////
 
     @Inject
-    private DepositView(BtcWalletService walletService,
+    private DepositView(XmrWalletService xmrWalletService,
                         Preferences preferences,
                         @Named(FormattingUtils.BTC_FORMATTER_KEY) CoinFormatter formatter) {
-        this.walletService = walletService;
+        this.xmrWalletService = xmrWalletService;
         this.preferences = preferences;
         this.formatter = formatter;
     }
@@ -143,7 +137,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
         usageColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.usage")));
 
         // trigger creation of at least 1 savings address
-        walletService.getFreshAddressEntry();
+        xmrWalletService.getFreshAddressEntry();
 
         tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
         tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.deposit.noAddresses")));
@@ -161,7 +155,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
 
         addressColumn.setComparator(Comparator.comparing(DepositListItem::getAddressString));
         balanceColumn.setComparator(Comparator.comparing(DepositListItem::getBalanceAsCoin));
-        confirmationsColumn.setComparator(Comparator.comparingDouble(o -> o.getTxConfidenceIndicator().getProgress()));
+        confirmationsColumn.setComparator(Comparator.comparingInt(o -> o.getNumConfirmationsSinceFirstUsed()));
         usageColumn.setComparator(Comparator.comparingInt(DepositListItem::getNumTxOutputs));
         tableView.getSortOrder().add(usageColumn);
         tableView.setItems(sortedList);
@@ -174,7 +168,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
         Tooltip.install(qrCodeImageView, new Tooltip(Res.get("shared.openLargeQRWindow")));
         qrCodeImageView.setOnMouseClicked(e -> GUIUtil.showFeeInfoBeforeExecute(
                 () -> UserThread.runAfter(
-                        () -> new QRCodeWindow(getBitcoinURI()).show(),
+                        () -> new QRCodeWindow(getPaymentUri()).show(),
                         200, TimeUnit.MILLISECONDS)));
         GridPane.setRowIndex(qrCodeImageView, gridRow);
         GridPane.setRowSpan(qrCodeImageView, 4);
@@ -201,23 +195,17 @@ public class DepositView extends ActivatableView<VBox, Void> {
 
         Tuple3<Button, CheckBox, HBox> buttonCheckBoxHBox = addButtonCheckBoxWithBox(gridPane, ++gridRow,
                 Res.get("funds.deposit.generateAddress"),
-                Res.get("funds.deposit.generateAddressSegwit"),
+                null,
                 15);
         buttonCheckBoxHBox.third.setSpacing(25);
         generateNewAddressButton = buttonCheckBoxHBox.first;
-        generateNewAddressSegwitCheckbox = buttonCheckBoxHBox.second;
-        generateNewAddressSegwitCheckbox.setAllowIndeterminate(false);
-        generateNewAddressSegwitCheckbox.setSelected(true);
 
         generateNewAddressButton.setOnAction(event -> {
-            boolean segwit = generateNewAddressSegwitCheckbox.isSelected();
-            NetworkParameters params = Config.baseCurrencyNetworkParameters();
-            boolean hasUnUsedAddress = observableList.stream().anyMatch(e -> e.getNumTxOutputs() == 0
-                            && (Address.fromString(params, e.getAddressString()) instanceof SegwitAddress)  == segwit);
+            boolean hasUnUsedAddress = observableList.stream().anyMatch(e -> e.getNumTxOutputs() == 0);
             if (hasUnUsedAddress) {
                 new Popup().warning(Res.get("funds.deposit.selectUnused")).show();
             } else {
-                AddressEntry newSavingsAddressEntry = walletService.getFreshAddressEntry(segwit);
+                XmrAddressEntry newSavingsAddressEntry = xmrWalletService.getNewAddressEntry();
                 updateList();
                 observableList.stream()
                         .filter(depositListItem -> depositListItem.getAddressString().equals(newSavingsAddressEntry.getAddressString()))
@@ -226,9 +214,9 @@ public class DepositView extends ActivatableView<VBox, Void> {
             }
         });
 
-        balanceListener = new BalanceListener() {
+        balanceListener = new XmrBalanceListener() {
             @Override
-            public void onBalanceChanged(Coin balance, Transaction tx) {
+            public void onBalanceChanged(BigInteger balance) {
                 updateList();
             }
         };
@@ -243,7 +231,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
 
         updateList();
 
-        walletService.addBalanceListener(balanceListener);
+        xmrWalletService.addBalanceListener(balanceListener);
         amountTextFieldSubscription = EasyBind.subscribe(amountTextField.textProperty(), t -> {
             addressTextField.setAmountAsCoin(ParsingUtils.parseToCoin(t, formatter));
             updateQRCode();
@@ -258,7 +246,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
         tableView.getSelectionModel().selectedItemProperty().removeListener(tableViewSelectionListener);
         sortedList.comparatorProperty().unbind();
         observableList.forEach(DepositListItem::cleanup);
-        walletService.removeBalanceListener(balanceListener);
+        xmrWalletService.removeBalanceListener(balanceListener);
         amountTextFieldSubscription.unsubscribe();
     }
 
@@ -267,7 +255,6 @@ public class DepositView extends ActivatableView<VBox, Void> {
     // UI handlers
     ///////////////////////////////////////////////////////////////////////////////////////////
 
-
     private void fillForm(String address) {
         titledGroupBg.setVisible(true);
         titledGroupBg.setManaged(true);
@@ -287,7 +274,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
     private void updateQRCode() {
         if (addressTextField.getAddress() != null && !addressTextField.getAddress().isEmpty()) {
             final byte[] imageBytes = QRCode
-                    .from(getBitcoinURI())
+                    .from(getPaymentUri())
                     .withSize(150, 150) // code has 41 elements 8 px is border with 150 we get 3x scale and min. border
                     .to(ImageType.PNG)
                     .stream()
@@ -309,8 +296,8 @@ public class DepositView extends ActivatableView<VBox, Void> {
     private void updateList() {
         observableList.forEach(DepositListItem::cleanup);
         observableList.clear();
-        walletService.getAvailableAddressEntries()
-                .forEach(e -> observableList.add(new DepositListItem(e, walletService, formatter)));
+        xmrWalletService.getAvailableAddressEntries()
+                .forEach(e -> observableList.add(new DepositListItem(e, xmrWalletService, formatter)));
     }
 
     private Coin getAmountAsCoin() {
@@ -318,10 +305,11 @@ public class DepositView extends ActivatableView<VBox, Void> {
     }
 
     @NotNull
-    private String getBitcoinURI() {
-        return GUIUtil.getBitcoinURI(addressTextField.getAddress(),
-                getAmountAsCoin(),
-                paymentLabelString);
+    private String getPaymentUri() {
+        return xmrWalletService.getWallet().createPaymentUri(new MoneroTxConfig()
+                .setAddress(addressTextField.getAddress())
+                .setAmount(ParsingUtils.coinToAtomicUnits(getAmountAsCoin()))
+                .setNote(paymentLabelString));
     }
 
     ///////////////////////////////////////////////////////////////////////////////////////////
@@ -434,7 +422,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
                                 super.updateItem(item, empty);
 
                                 if (item != null && !empty) {
-                                    setGraphic(item.getTxConfidenceIndicator());
+                                    //setGraphic(item.getTxConfidenceIndicator());
                                 } else {
                                     setGraphic(null);
                                 }
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java
index c0dc9231..33d74992 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java
@@ -17,34 +17,34 @@
 
 package bisq.desktop.main.funds.transactions;
 
-import bisq.desktop.components.indicator.TxConfidenceIndicator;
-
-import bisq.core.btc.listeners.TxConfidenceListener;
 import bisq.core.btc.wallet.XmrWalletService;
+import bisq.core.locale.Res;
+import bisq.core.offer.Offer;
+import bisq.core.offer.OpenOffer;
 import bisq.core.trade.Tradable;
+import bisq.core.trade.Trade;
+import bisq.core.util.ParsingUtils;
 import bisq.core.util.coin.CoinFormatter;
-
-import org.bitcoinj.core.Coin;
-
+import bisq.desktop.components.indicator.TxConfidenceIndicator;
+import bisq.desktop.util.DisplayUtils;
+import bisq.desktop.util.GUIUtil;
+import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
-
-import javafx.scene.control.Tooltip;
-
+import java.math.BigInteger;
 import java.util.Date;
-import java.util.function.Supplier;
-
+import java.util.Optional;
+import javafx.scene.control.Tooltip;
+import javax.annotation.Nullable;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
-
-import javax.annotation.Nullable;
-
-
-
+import monero.wallet.model.MoneroIncomingTransfer;
+import monero.wallet.model.MoneroOutgoingTransfer;
 import monero.wallet.model.MoneroTxWallet;
+import monero.wallet.model.MoneroWalletListener;
+import org.bitcoinj.core.Coin;
 
 @Slf4j
 class TransactionsListItem {
-    private final XmrWalletService xmrWalletService;
     private final CoinFormatter formatter;
     private String dateString;
     private final Date date;
@@ -54,12 +54,11 @@ class TransactionsListItem {
     private String details = "";
     private String addressString = "";
     private String direction = "";
-    private TxConfidenceListener txConfidenceListener;
     private boolean received;
     private boolean detailsAvailable;
     private Coin amountAsCoin = Coin.ZERO;
     private String memo = "";
-    private int confirmations = 0;
+    private long confirmations = 0;
     @Getter
     private final boolean isDustAttackTx;
     private boolean initialTxConfidenceVisibility = true;
@@ -77,187 +76,140 @@ class TransactionsListItem {
     // used at exportCSV
     TransactionsListItem() {
         date = null;
-        xmrWalletService = null;
         txId = null;
         formatter = null;
         isDustAttackTx = false;
         lazyFieldsSupplier = null;
     }
 
-    TransactionsListItem(MoneroTxWallet transaction,
+    TransactionsListItem(MoneroTxWallet tx,
                          XmrWalletService xmrWalletService,
                          TransactionAwareTradable transactionAwareTradable,
                          CoinFormatter formatter,
                          long ignoreDustThreshold) {
-        throw new RuntimeException("TransactionsListItem needs updated to use XMR wallet");
-//        this.btcWalletService = btcWalletService;
-//        this.formatter = formatter;
-//        this.memo = transaction.getMemo();
-//
-//        txId = transaction.getTxId().toString();
-//
-//        Optional<Tradable> optionalTradable = Optional.ofNullable(transactionAwareTradable)
-//                .map(TransactionAwareTradable::asTradable);
-//
-//        Coin valueSentToMe = btcWalletService.getValueSentToMeForTransaction(transaction);
-//        Coin valueSentFromMe = btcWalletService.getValueSentFromMeForTransaction(transaction);
-//
-//        // TODO check and refactor
-//        if (valueSentToMe.isZero()) {
-//            amountAsCoin = valueSentFromMe.multiply(-1);
-//            for (TransactionOutput output : transaction.getOutputs()) {
-//                if (!btcWalletService.isTransactionOutputMine(output)) {
-//                    received = false;
-//                    if (WalletService.isOutputScriptConvertibleToAddress(output)) {
-//                        addressString = WalletService.getAddressStringFromOutput(output);
-//                        direction = Res.get("funds.tx.direction.sentTo");
-//                        break;
-//                    }
-//                }
-//            }
-//        } else if (valueSentFromMe.isZero()) {
-//            amountAsCoin = valueSentToMe;
-//            direction = Res.get("funds.tx.direction.receivedWith");
-//            received = true;
-//            for (TransactionOutput output : transaction.getOutputs()) {
-//                if (btcWalletService.isTransactionOutputMine(output) &&
-//                        WalletService.isOutputScriptConvertibleToAddress(output)) {
-//                    addressString = WalletService.getAddressStringFromOutput(output);
-//                    break;
-//                }
-//            }
-//        } else {
-//            amountAsCoin = valueSentToMe.subtract(valueSentFromMe);
-//            boolean outgoing = false;
-//            for (TransactionOutput output : transaction.getOutputs()) {
-//                if (!btcWalletService.isTransactionOutputMine(output)) {
-//                    if (WalletService.isOutputScriptConvertibleToAddress(output)) {
-//                        addressString = WalletService.getAddressStringFromOutput(output);
-//                        outgoing = true;
-//                        break;
-//                    }
-//                } else {
-//                    addressString = WalletService.getAddressStringFromOutput(output);
-//                    outgoing = (valueSentToMe.getValue() < valueSentFromMe.getValue());
-//                    if (!outgoing) {
-//                        direction = Res.get("funds.tx.direction.receivedWith");
-//                        received = true;
-//                    }
-//                }
-//            }
-//
-//            if (outgoing) {
-//                direction = Res.get("funds.tx.direction.sentTo");
-//                received = false;
-//            }
-//        }
-//
-//
-//        if (optionalTradable.isPresent()) {
-//            tradable = optionalTradable.get();
-//            detailsAvailable = true;
-//            String tradeId = tradable.getShortId();
-//            if (tradable instanceof OpenOffer) {
-//                details = Res.get("funds.tx.createOfferFee", tradeId);
-//            } else if (tradable instanceof Trade) {
-//                Trade trade = (Trade) tradable;
-//                TransactionAwareTrade transactionAwareTrade = (TransactionAwareTrade) transactionAwareTradable;
-//                if (trade.getTakerFeeTxId() != null && trade.getTakerFeeTxId().equals(txId)) {
-//                    details = Res.get("funds.tx.takeOfferFee", tradeId);
-//                } else {
-//                    Offer offer = trade.getOffer();
-//                    String offerFeePaymentTxID = offer.getOfferFeePaymentTxId();
-//                    if (offerFeePaymentTxID != null && offerFeePaymentTxID.equals(txId)) {
-//                        details = Res.get("funds.tx.createOfferFee", tradeId);
-//                    } else if (trade.getDepositTx() != null &&
-//                            trade.getDepositTx().getTxId().equals(Sha256Hash.wrap(txId))) {
-//                        details = Res.get("funds.tx.multiSigDeposit", tradeId);
-//                    } else if (trade.getPayoutTx() != null &&
-//                            trade.getPayoutTx().getTxId().equals(Sha256Hash.wrap(txId))) {
-//                        details = Res.get("funds.tx.multiSigPayout", tradeId);
-//
-//                        if (amountAsCoin.isZero()) {
-//                            initialTxConfidenceVisibility = false;
-//                        }
-//                    } else {
-//                        Trade.DisputeState disputeState = trade.getDisputeState();
-//                        if (disputeState == Trade.DisputeState.DISPUTE_CLOSED) {
-//                            if (valueSentToMe.isPositive()) {
-//                                details = Res.get("funds.tx.disputePayout", tradeId);
-//                            } else {
-//                                details = Res.get("funds.tx.disputeLost", tradeId);
-//                                initialTxConfidenceVisibility = false;
-//                            }
-//                        } else if (disputeState == Trade.DisputeState.REFUND_REQUEST_CLOSED ||
-//                                disputeState == Trade.DisputeState.REFUND_REQUESTED ||
-//                                disputeState == Trade.DisputeState.REFUND_REQUEST_STARTED_BY_PEER) {
-//                            if (valueSentToMe.isPositive()) {
-//                                details = Res.get("funds.tx.refund", tradeId);
-//                            } else {
-//                                // We have spent the deposit tx outputs to the Bisq donation address to enable
-//                                // the refund process (refund agent -> reimbursement). As the funds have left our wallet
-//                                // already when funding the deposit tx we show 0 BTC as amount.
-//                                // Confirmation is not known from the BitcoinJ side (not 100% clear why) as no funds
-//                                // left our wallet nor we received funds. So we set indicator invisible.
-//                                amountAsCoin = Coin.ZERO;
-//                                details = Res.get("funds.tx.collateralForRefund", tradeId);
-//                                initialTxConfidenceVisibility = false;
-//                            }
-//                        } else {
-//                            if (transactionAwareTrade.isDelayedPayoutTx(txId)) {
-//                                details = Res.get("funds.tx.timeLockedPayoutTx", tradeId);
-//                                initialTxConfidenceVisibility = false;
-//                            } else {
-//                                details = Res.get("funds.tx.unknown", tradeId);
-//                            }
-//                        }
-//                    }
-//                }
-//            }
-//        } else {
-//            if (amountAsCoin.isZero()) {
-//                details = Res.get("funds.tx.noFundsFromDispute");
-//                initialTxConfidenceVisibility = false;
-//        }
-//        // Use tx.getIncludedInBestChainAt() when available, otherwise use tx.getUpdateTime()
-//        date = transaction.getIncludedInBestChainAt() != null ? transaction.getIncludedInBestChainAt() : transaction.getUpdateTime();
-//        dateString = DisplayUtils.formatDateTime(date);
-//
-//        isDustAttackTx = received && valueSentToMe.value < ignoreDustThreshold;
-//        if (isDustAttackTx) {
-//            details = Res.get("funds.tx.dustAttackTx");
-//        }
-//
-//        // confidence
-//        lazyFieldsSupplier = Suppliers.memoize(() -> new LazyFields() {{
-//            txConfidenceIndicator = new TxConfidenceIndicator();
-//            txConfidenceIndicator.setId("funds-confidence");
-//            tooltip = new Tooltip(Res.get("shared.notUsedYet"));
-//            txConfidenceIndicator.setProgress(0);
-//            txConfidenceIndicator.setTooltip(tooltip);
-//            txConfidenceIndicator.setVisible(initialTxConfidenceVisibility);
-//
-//            TransactionConfidence confidence = transaction.getConfidence();
-//            GUIUtil.updateConfidence(confidence, tooltip, txConfidenceIndicator);
-//            confirmations = confidence.getDepthInBlocks();
-//        }});
-//
-//        txConfidenceListener = new TxConfidenceListener(txId) {
-//            @Override
-//            public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
-//                GUIUtil.updateConfidence(confidence, lazy().tooltip, lazy().txConfidenceIndicator);
-//                confirmations = confidence.getDepthInBlocks();
-//            }
-//        };
-//        btcWalletService.addTxConfidenceListener(txConfidenceListener);
+        this.formatter = formatter;
+        this.memo = tx.getNote();
+        this.txId = tx.getHash();
+        
+        Optional<Tradable> optionalTradable = Optional.ofNullable(transactionAwareTradable)
+                .map(TransactionAwareTradable::asTradable);
+
+        Coin valueSentToMe = ParsingUtils.atomicUnitsToCoin(tx.getIncomingAmount() == null ? new BigInteger("0") : tx.getIncomingAmount());
+        Coin valueSentFromMe = ParsingUtils.atomicUnitsToCoin(tx.getOutgoingAmount() == null ? new BigInteger("0") : tx.getOutgoingAmount());
+
+        if (tx.getTransfers().get(0).isIncoming()) {
+            addressString = ((MoneroIncomingTransfer) tx.getTransfers().get(0)).getAddress();
+        } else {
+            MoneroOutgoingTransfer transfer = (MoneroOutgoingTransfer) tx.getTransfers().get(0);
+            if (transfer.getDestinations() != null) addressString = transfer.getDestinations().get(0).getAddress();
+            else addressString = "unavailable";
+        }
+
+        if (valueSentFromMe.isZero()) {
+            amountAsCoin = valueSentToMe;
+            direction = Res.get("funds.tx.direction.receivedWith");
+            received = true;
+        } else {
+            amountAsCoin = valueSentFromMe.multiply(-1);
+            received = false;
+            direction = Res.get("funds.tx.direction.sentTo");
+        }
+
+        if (optionalTradable.isPresent()) {
+            tradable = optionalTradable.get();
+            detailsAvailable = true;
+            String tradeId = tradable.getShortId();
+            if (tradable instanceof OpenOffer) {
+                details = Res.get("funds.tx.createOfferFee", tradeId);
+            } else if (tradable instanceof Trade) {
+                Trade trade = (Trade) tradable;
+                if (trade.getTakerFeeTxId() != null && trade.getTakerFeeTxId().equals(txId)) {
+                    details = Res.get("funds.tx.takeOfferFee", tradeId);
+                } else {
+                    Offer offer = trade.getOffer();
+                    String offerFeePaymentTxID = offer.getOfferFeePaymentTxId();
+                    if (offerFeePaymentTxID != null && offerFeePaymentTxID.equals(txId)) {
+                        details = Res.get("funds.tx.createOfferFee", tradeId);
+                    } else if (trade.getSelf().getDepositTxHash() != null &&
+                            trade.getSelf().getDepositTxHash().equals(txId)) {
+                        details = Res.get("funds.tx.multiSigDeposit", tradeId);
+                    } else if (trade.getPayoutTxId() != null &&
+                            trade.getPayoutTxId().equals(txId)) {
+                        details = Res.get("funds.tx.multiSigPayout", tradeId);
+                      if (amountAsCoin.isZero()) {
+                        initialTxConfidenceVisibility = false;
+                      }
+                    } else {
+                        Trade.DisputeState disputeState = trade.getDisputeState();
+                        if (disputeState == Trade.DisputeState.DISPUTE_CLOSED) {
+                            if (valueSentToMe.isPositive()) {
+                                details = Res.get("funds.tx.disputePayout", tradeId);
+                            } else {
+                                details = Res.get("funds.tx.disputeLost", tradeId);
+                            }
+                        } else if (disputeState == Trade.DisputeState.REFUND_REQUEST_CLOSED ||
+                                disputeState == Trade.DisputeState.REFUND_REQUESTED ||
+                                disputeState == Trade.DisputeState.REFUND_REQUEST_STARTED_BY_PEER) {
+                            if (valueSentToMe.isPositive()) {
+                                details = Res.get("funds.tx.refund", tradeId);
+                            } else {
+                                // We have spent the deposit tx outputs to the Bisq donation address to enable
+                                // the refund process (refund agent -> reimbursement). As the funds have left our wallet
+                                // already when funding the deposit tx we show 0 BTC as amount.
+                                // Confirmation is not known from the BitcoinJ side (not 100% clear why) as no funds
+                                // left our wallet nor we received funds. So we set indicator invisible.
+                                amountAsCoin = Coin.ZERO;
+                                details = Res.get("funds.tx.collateralForRefund", tradeId);
+                                initialTxConfidenceVisibility = false;
+                            }
+                        } else {
+                            details = Res.get("funds.tx.unknown", tradeId);
+                        }
+                    }
+                }
+            }
+        } else {
+            if (amountAsCoin.isZero()) {
+                details = Res.get("funds.tx.noFundsFromDispute");
+            }
+        }
+
+        this.date = new Date(0); // TODO: convert height to date
+        dateString = DisplayUtils.formatDateTime(date);
+
+        isDustAttackTx = received && valueSentToMe.value < ignoreDustThreshold;
+        if (isDustAttackTx) {
+            details = Res.get("funds.tx.dustAttackTx");
+        }
+        
+        // confidence
+        lazyFieldsSupplier = Suppliers.memoize(() -> new LazyFields() {{
+            txConfidenceIndicator = new TxConfidenceIndicator();
+            txConfidenceIndicator.setId("funds-confidence");
+            tooltip = new Tooltip(Res.get("shared.notUsedYet"));
+            txConfidenceIndicator.setProgress(0);
+            txConfidenceIndicator.setTooltip(tooltip);
+            txConfidenceIndicator.setVisible(initialTxConfidenceVisibility);
+
+            GUIUtil.updateConfidence(tx, tooltip, txConfidenceIndicator);
+            confirmations = tx.getNumConfirmations();
+        }});
+
+        // listen for tx updates
+        // TODO: this only listens for new blocks, listen for double spend
+        xmrWalletService.addWalletListener(new MoneroWalletListener() {
+            @Override
+            public void onNewBlock(long height) {
+                MoneroTxWallet tx = xmrWalletService.getWallet().getTx(txId);
+                GUIUtil.updateConfidence(tx, lazy().tooltip, lazy().txConfidenceIndicator);
+                confirmations = tx.getNumConfirmations();
+            }
+        });
     }
 
     public void cleanup() {
-        // TODO (woodser): remove wallet listener
-        //xmrWalletService.removeTxConfidenceListener(txConfidenceListener);
     }
 
-
     public TxConfidenceIndicator getTxConfidenceIndicator() {
         return lazy().txConfidenceIndicator;
     }
@@ -309,8 +261,8 @@ class TransactionsListItem {
         return tradable;
     }
 
-    public String getNumConfirmations() {
-        return String.valueOf(confirmations);
+    public long getNumConfirmations() {
+        return confirmations;
     }
 
     public String getMemo() {
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
index 2ee13f5f..cbc57d3f 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsView.java
@@ -29,10 +29,9 @@ import bisq.desktop.main.overlays.windows.OfferDetailsWindow;
 import bisq.desktop.main.overlays.windows.TradeDetailsWindow;
 import bisq.desktop.util.GUIUtil;
 import bisq.core.api.CoreMoneroConnectionsService;
-import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Res;
 import bisq.core.offer.OpenOffer;
-import bisq.core.trade.Tradable;
 import bisq.core.trade.Trade;
 import bisq.core.user.Preferences;
 
@@ -40,13 +39,10 @@ import bisq.network.p2p.P2PService;
 
 import bisq.common.util.Utilities;
 
-import org.bitcoinj.core.TransactionConfidence;
-import org.bitcoinj.wallet.listeners.WalletChangeEventListener;
-
 import com.googlecode.jcsv.writer.CSVEntryConverter;
 
 import javax.inject.Inject;
-
+import monero.wallet.model.MoneroWalletListener;
 import de.jensd.fx.fontawesome.AwesomeIcon;
 
 import javafx.fxml.FXML;
@@ -77,11 +73,9 @@ import javafx.collections.ObservableList;
 import javafx.collections.transformation.SortedList;
 
 import javafx.util.Callback;
-
+import java.math.BigInteger;
 import java.util.Comparator;
 
-import javax.annotation.Nullable;
-
 @FxmlView
 public class TransactionsView extends ActivatableView<VBox, Void> {
 
@@ -100,33 +94,40 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
     private final DisplayedTransactions displayedTransactions;
     private final SortedList<TransactionsListItem> sortedDisplayedTransactions;
 
-    private final BtcWalletService btcWalletService;
-    private final P2PService p2PService;
-    private final CoreMoneroConnectionsService connectionService;
+    private final XmrWalletService xmrWalletService;
     private final Preferences preferences;
     private final TradeDetailsWindow tradeDetailsWindow;
     private final OfferDetailsWindow offerDetailsWindow;
 
-    private WalletChangeEventListener walletChangeEventListener;
-
     private EventHandler<KeyEvent> keyEventEventHandler;
     private Scene scene;
 
+    private TransactionsUpdater transactionsUpdater = new TransactionsUpdater();
+
+    private class TransactionsUpdater extends MoneroWalletListener {
+        @Override
+        public void onNewBlock(long height) {
+            displayedTransactions.update();
+        }
+        @Override
+        public void onBalancesChanged(BigInteger newBalance, BigInteger newUnlockedBalance) {
+            displayedTransactions.update();
+        }
+    }
+    
     ///////////////////////////////////////////////////////////////////////////////////////////
     // Constructor, lifecycle
     ///////////////////////////////////////////////////////////////////////////////////////////
 
     @Inject
-    private TransactionsView(BtcWalletService btcWalletService,
+    private TransactionsView(XmrWalletService xmrWalletService,
                              P2PService p2PService,
                              CoreMoneroConnectionsService connectionService,
                              Preferences preferences,
                              TradeDetailsWindow tradeDetailsWindow,
                              OfferDetailsWindow offerDetailsWindow,
                              DisplayedTransactionsFactory displayedTransactionsFactory) {
-        this.btcWalletService = btcWalletService;
-        this.p2PService = p2PService;
-        this.connectionService = connectionService;
+        this.xmrWalletService = xmrWalletService;
         this.preferences = preferences;
         this.tradeDetailsWindow = tradeDetailsWindow;
         this.offerDetailsWindow = offerDetailsWindow;
@@ -168,16 +169,12 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
         addressColumn.setComparator(Comparator.comparing(item -> item.getDirection() + item.getAddressString()));
         transactionColumn.setComparator(Comparator.comparing(TransactionsListItem::getTxId));
         amountColumn.setComparator(Comparator.comparing(TransactionsListItem::getAmountAsCoin));
-        confidenceColumn.setComparator(Comparator.comparingDouble(item -> item.getTxConfidenceIndicator().getProgress()));
+        confidenceColumn.setComparator(Comparator.comparingLong(item -> item.getNumConfirmations()));
         memoColumn.setComparator(Comparator.comparing(TransactionsListItem::getMemo));
 
         dateColumn.setSortType(TableColumn.SortType.DESCENDING);
         tableView.getSortOrder().add(dateColumn);
 
-        walletChangeEventListener = wallet -> {
-            displayedTransactions.update();
-        };
-
         keyEventEventHandler = event -> {
             // Not intended to be public to users as the feature is not well tested
             if (Utilities.isAltOrCtrlPressed(KeyCode.R, event)) {
@@ -202,7 +199,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
         tableView.setItems(sortedDisplayedTransactions);
         displayedTransactions.update();
 
-        btcWalletService.addChangeEventListener(walletChangeEventListener);
+        xmrWalletService.addWalletListener(transactionsUpdater);
 
         scene = root.getScene();
         if (scene != null)
@@ -226,7 +223,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
                 columns[3] = item.getTxId();
                 columns[4] = item.getAmount();
                 columns[5] = item.getMemo() == null ? "" : item.getMemo();
-                columns[6] = item.getNumConfirmations();
+                columns[6] = String.valueOf(item.getNumConfirmations());
                 return columns;
             };
 
@@ -239,7 +236,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
     protected void deactivate() {
         sortedDisplayedTransactions.comparatorProperty().unbind();
         displayedTransactions.forEach(TransactionsListItem::cleanup);
-        btcWalletService.removeChangeEventListener(walletChangeEventListener);
+        xmrWalletService.removeWalletListener(transactionsUpdater);
 
         if (scene != null)
             scene.removeEventHandler(KeyEvent.KEY_RELEASED, keyEventEventHandler);
@@ -505,49 +502,15 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
                             @Override
                             public void updateItem(final TransactionsListItem item, boolean empty) {
                                 super.updateItem(item, empty);
-                                if (item != null && !empty) {
-                                    TransactionConfidence confidence = btcWalletService.getConfidenceForTxId(item.getTxId());
-                                    if (confidence != null) {
-                                        if (confidence.getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING) {
-                                            if (button == null) {
-                                                button = new AutoTooltipButton(Res.get("funds.tx.revert"));
-                                                setGraphic(button);
-                                            }
-                                            button.setOnAction(e -> revertTransaction(item.getTxId(), item.getTradable()));
-                                        } else {
-                                            setGraphic(null);
-                                            if (button != null) {
-                                                button.setOnAction(null);
-                                                button = null;
-                                            }
-                                        }
-                                    }
-                                } else {
-                                    setGraphic(null);
-                                    if (button != null) {
-                                        button.setOnAction(null);
-                                        button = null;
-                                    }
+                                setGraphic(null);
+                                if (button != null) {
+                                    button.setOnAction(null);
+                                    button = null;
                                 }
                             }
                         };
                     }
                 });
     }
-
-    private void revertTransaction(String txId, @Nullable Tradable tradable) {
-        if (GUIUtil.isReadyForTxBroadcastOrShowPopup(p2PService, connectionService)) {
-            try {
-                btcWalletService.doubleSpendTransaction(txId, () -> {
-                    if (tradable != null)
-                        btcWalletService.swapAnyTradeEntryContextToAvailableEntry(tradable.getId());
-
-                    new Popup().information(Res.get("funds.tx.txSent")).show();
-                }, errorMessage -> new Popup().warning(errorMessage).show());
-            } catch (Throwable e) {
-                new Popup().warning(e.getMessage()).show();
-            }
-        }
-    }
 }
 
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java
index 9928a6cc..b37d3958 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalListItem.java
@@ -23,6 +23,7 @@ import bisq.core.btc.listeners.XmrBalanceListener;
 import bisq.core.btc.model.XmrAddressEntry;
 import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Res;
+import bisq.core.util.ParsingUtils;
 import bisq.core.util.coin.CoinFormatter;
 
 import org.bitcoinj.core.Coin;
@@ -71,7 +72,8 @@ class WithdrawalListItem {
     }
 
     private void updateBalance() {
-        balance = walletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
+        balance = walletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex()); // TODO: Coin represents centineros everywhere, but here it's atomic units. reconcile
+        balance = Coin.valueOf(ParsingUtils.atomicUnitsToCentineros(balance.longValue())); // in centineros
         if (balance != null)
             balanceLabel.setText(formatter.formatCoin(this.balance));
     }
diff --git a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java
index e171e536..846b0b5e 100644
--- a/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java
+++ b/desktop/src/main/java/bisq/desktop/main/funds/withdrawal/WithdrawalView.java
@@ -26,16 +26,20 @@ import bisq.desktop.components.HyperlinkWithIcon;
 import bisq.desktop.components.InputTextField;
 import bisq.desktop.components.TitledGroupBg;
 import bisq.desktop.main.overlays.popups.Popup;
+import bisq.desktop.main.overlays.windows.TxDetails;
 import bisq.desktop.main.overlays.windows.WalletPasswordWindow;
 import bisq.desktop.util.GUIUtil;
 import bisq.desktop.util.Layout;
 
 import bisq.core.btc.listeners.XmrBalanceListener;
+import bisq.core.btc.model.XmrAddressEntry;
 import bisq.core.btc.setup.WalletsSetup;
 import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Res;
 import bisq.core.provider.fee.FeeService;
+import bisq.core.trade.Trade;
 import bisq.core.trade.TradeManager;
+import bisq.core.user.DontShowAgainLookup;
 import bisq.core.user.Preferences;
 import bisq.core.util.FormattingUtils;
 import bisq.core.util.ParsingUtils;
@@ -43,17 +47,15 @@ import bisq.core.util.coin.CoinFormatter;
 import bisq.core.util.validation.BtcAddressValidator;
 
 import bisq.network.p2p.P2PService;
-
+import bisq.common.util.Tuple2;
 import bisq.common.util.Tuple3;
-import bisq.common.util.Tuple4;
 
 import org.bitcoinj.core.Coin;
-import org.bitcoinj.core.Transaction;
 
 import javax.inject.Inject;
 import javax.inject.Named;
-
-import com.google.common.util.concurrent.FutureCallback;
+import monero.wallet.model.MoneroTxConfig;
+import monero.wallet.model.MoneroTxWallet;
 
 import org.apache.commons.lang3.StringUtils;
 
@@ -69,7 +71,6 @@ import javafx.scene.control.TableColumn;
 import javafx.scene.control.TableView;
 import javafx.scene.control.TextField;
 import javafx.scene.control.Toggle;
-import javafx.scene.control.ToggleButton;
 import javafx.scene.control.ToggleGroup;
 import javafx.scene.control.Tooltip;
 import javafx.scene.layout.GridPane;
@@ -88,12 +89,12 @@ import javafx.collections.transformation.SortedList;
 
 import javafx.util.Callback;
 
-import org.bouncycastle.crypto.params.KeyParameter;
 
 import java.math.BigInteger;
-
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -109,36 +110,27 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
     @FXML
     TableColumn<WithdrawalListItem, WithdrawalListItem> addressColumn, balanceColumn, selectColumn;
 
-    private RadioButton useAllInputsRadioButton, useCustomInputsRadioButton, feeExcludedRadioButton, feeIncludedRadioButton;
+    private RadioButton useAllInputsRadioButton, useCustomInputsRadioButton;
     private Label amountLabel;
-    private TextField amountTextField, withdrawFromTextField, withdrawToTextField, withdrawMemoTextField, transactionFeeInputTextField;
+    private TextField amountTextField, withdrawFromTextField, withdrawToTextField, withdrawMemoTextField;
 
     private final XmrWalletService xmrWalletService;
     private final TradeManager tradeManager;
     private final P2PService p2PService;
-    private final WalletsSetup walletsSetup;
     private final CoinFormatter formatter;
     private final Preferences preferences;
-    private final BtcAddressValidator btcAddressValidator;
-    private final WalletPasswordWindow walletPasswordWindow;
     private final ObservableList<WithdrawalListItem> observableList = FXCollections.observableArrayList();
     private final SortedList<WithdrawalListItem> sortedList = new SortedList<>(observableList);
     private final Set<WithdrawalListItem> selectedItems = new HashSet<>();
     private XmrBalanceListener balanceListener;
-    private Set<String> fromAddresses = new HashSet<>();
     private Coin totalAvailableAmountOfSelectedItems = Coin.ZERO;
     private Coin amountAsCoin = Coin.ZERO;
     private ChangeListener<String> amountListener;
-    private ChangeListener<Boolean> amountFocusListener, useCustomFeeCheckboxListener, transactionFeeFocusedListener;
-    private ChangeListener<Toggle> feeToggleGroupListener, inputsToggleGroupListener;
-    private ChangeListener<Number> transactionFeeChangeListener;
-    private ToggleGroup feeToggleGroup, inputsToggleGroup;
-    private ToggleButton useCustomFee;
+    private ChangeListener<Boolean> amountFocusListener;
+    private ChangeListener<Toggle> inputsToggleGroupListener;
+    private ToggleGroup inputsToggleGroup;
     private final BooleanProperty useAllInputs = new SimpleBooleanProperty(true);
-    private boolean feeExcluded;
     private int rowIndex = 0;
-    private final FeeService feeService;
-
 
     ///////////////////////////////////////////////////////////////////////////////////////////
     // Constructor, lifecycle
@@ -154,16 +146,11 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
                            BtcAddressValidator btcAddressValidator,
                            WalletPasswordWindow walletPasswordWindow,
                            FeeService feeService) {
-//        throw new RuntimeException("WithdrawalView needs updated to use XMR wallet");
         this.xmrWalletService = xmrWalletService;
         this.tradeManager = tradeManager;
         this.p2PService = p2PService;
-        this.walletsSetup = walletsSetup;
         this.formatter = formatter;
         this.preferences = preferences;
-        this.btcAddressValidator = btcAddressValidator;
-        this.walletPasswordWindow = walletPasswordWindow;
-        this.feeService = feeService;
     }
 
     @Override
@@ -189,20 +176,13 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         useAllInputsRadioButton = labelRadioButtonRadioButtonTuple3.second;
         useCustomInputsRadioButton = labelRadioButtonRadioButtonTuple3.third;
 
-        feeToggleGroup = new ToggleGroup();
-
-        final Tuple4<Label, TextField, RadioButton, RadioButton> feeTuple3 = addTopLabelTextFieldRadioButtonRadioButton(gridPane, ++rowIndex, feeToggleGroup,
+        final Tuple2<Label, InputTextField> feeTuple3 = addTopLabelInputTextField(gridPane, ++rowIndex,
                 Res.get("funds.withdrawal.receiverAmount", Res.getBaseCurrencyCode()),
-                "",
-                Res.get("funds.withdrawal.feeExcluded"),
-                Res.get("funds.withdrawal.feeIncluded"),
                 0);
 
         amountLabel = feeTuple3.first;
         amountTextField = feeTuple3.second;
         amountTextField.setMinWidth(180);
-        feeExcludedRadioButton = feeTuple3.third;
-        feeIncludedRadioButton = feeTuple3.fourth;
 
         withdrawFromTextField = addTopLabelTextField(gridPane, ++rowIndex,
                 Res.get("funds.withdrawal.fromLabel", Res.getBaseCurrencyCode())).second;
@@ -213,52 +193,6 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         withdrawMemoTextField = addTopLabelInputTextField(gridPane, ++rowIndex,
                 Res.get("funds.withdrawal.memoLabel", Res.getBaseCurrencyCode())).second;
 
-        Tuple3<Label, InputTextField, ToggleButton> customFeeTuple = addTopLabelInputTextFieldSlideToggleButton(gridPane, ++rowIndex,
-                Res.get("funds.withdrawal.txFee"), Res.get("funds.withdrawal.useCustomFeeValue"));
-        transactionFeeInputTextField = customFeeTuple.second;
-        useCustomFee = customFeeTuple.third;
-
-        useCustomFeeCheckboxListener = (observable, oldValue, newValue) -> {
-            transactionFeeInputTextField.setEditable(newValue);
-            if (!newValue) {
-                try {
-                    transactionFeeInputTextField.setText(String.valueOf(feeService.getTxFeePerVbyte().value));
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        };
-
-        transactionFeeFocusedListener = (o, oldValue, newValue) -> {
-            if (oldValue && !newValue) {
-                String estimatedFee = String.valueOf(feeService.getTxFeePerVbyte().value);
-                try {
-                    int withdrawalTxFeePerVbyte = Integer.parseInt(transactionFeeInputTextField.getText());
-                    final long minFeePerVbyte = feeService.getMinFeePerVByte();
-                    if (withdrawalTxFeePerVbyte < minFeePerVbyte) {
-                        new Popup().warning(Res.get("funds.withdrawal.txFeeMin", minFeePerVbyte)).show();
-                        transactionFeeInputTextField.setText(estimatedFee);
-                    } else if (withdrawalTxFeePerVbyte > 5000) {
-                        new Popup().warning(Res.get("funds.withdrawal.txFeeTooLarge")).show();
-                        transactionFeeInputTextField.setText(estimatedFee);
-                    } else {
-                        preferences.setWithdrawalTxFeeInVbytes(withdrawalTxFeePerVbyte);
-                    }
-                } catch (NumberFormatException t) {
-                    log.error(t.toString());
-                    t.printStackTrace();
-                    new Popup().warning(Res.get("validation.integerOnly")).show();
-                    transactionFeeInputTextField.setText(estimatedFee);
-                } catch (Throwable t) {
-                    log.error(t.toString());
-                    t.printStackTrace();
-                    new Popup().warning(Res.get("validation.inputError", t.getMessage())).show();
-                    transactionFeeInputTextField.setText(estimatedFee);
-                }
-            }
-        };
-        transactionFeeChangeListener = (observable, oldValue, newValue) -> transactionFeeInputTextField.setText(String.valueOf(feeService.getTxFeePerVbyte().value));
-
         final Button withdrawButton = addButton(gridPane, ++rowIndex, Res.get("funds.withdrawal.withdrawButton"), 15);
 
         withdrawButton.setOnAction(event -> onWithdraw());
@@ -304,14 +238,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
                     amountTextField.setText("");
             }
         };
-        feeExcludedRadioButton.setToggleGroup(feeToggleGroup);
-        feeIncludedRadioButton.setToggleGroup(feeToggleGroup);
-        feeToggleGroupListener = (observable, oldValue, newValue) -> {
-            feeExcluded = newValue == feeExcludedRadioButton;
-            amountLabel.setText(feeExcluded ?
-                    Res.get("funds.withdrawal.receiverAmount") :
-                    Res.get("funds.withdrawal.senderAmount"));
-        };
+        amountLabel.setText(Res.get("funds.withdrawal.receiverAmount"));
     }
 
     private void updateInputSelection() {
@@ -333,22 +260,11 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         amountTextField.textProperty().addListener(amountListener);
         amountTextField.focusedProperty().addListener(amountFocusListener);
         xmrWalletService.addBalanceListener(balanceListener);
-        feeToggleGroup.selectedToggleProperty().addListener(feeToggleGroupListener);
         inputsToggleGroup.selectedToggleProperty().addListener(inputsToggleGroupListener);
 
-        if (feeToggleGroup.getSelectedToggle() == null)
-            feeToggleGroup.selectToggle(feeIncludedRadioButton);
-
         if (inputsToggleGroup.getSelectedToggle() == null)
             inputsToggleGroup.selectToggle(useAllInputsRadioButton);
 
-        useCustomFee.setSelected(false);
-        transactionFeeInputTextField.setEditable(false);
-        transactionFeeInputTextField.setText(String.valueOf(feeService.getTxFeePerVbyte().value));
-        feeService.feeUpdateCounterProperty().addListener(transactionFeeChangeListener);
-        useCustomFee.selectedProperty().addListener(useCustomFeeCheckboxListener);
-        transactionFeeInputTextField.focusedProperty().addListener(transactionFeeFocusedListener);
-
         updateInputSelection();
         GUIUtil.requestFocus(withdrawToTextField);
     }
@@ -360,12 +276,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         xmrWalletService.removeBalanceListener(balanceListener);
         amountTextField.textProperty().removeListener(amountListener);
         amountTextField.focusedProperty().removeListener(amountFocusListener);
-        feeToggleGroup.selectedToggleProperty().removeListener(feeToggleGroupListener);
         inputsToggleGroup.selectedToggleProperty().removeListener(inputsToggleGroupListener);
-        transactionFeeInputTextField.focusedProperty().removeListener(transactionFeeFocusedListener);
-        if (transactionFeeChangeListener != null)
-            feeService.feeUpdateCounterProperty().removeListener(transactionFeeChangeListener);
-        useCustomFee.selectedProperty().removeListener(useCustomFeeCheckboxListener);
     }
 
 
@@ -374,108 +285,72 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
     ///////////////////////////////////////////////////////////////////////////////////////////
 
     private void onWithdraw() {
-        throw new RuntimeException("WithdrawalView.onWithdraw() not updated to XMR");
-//        if (GUIUtil.isReadyForTxBroadcastOrShowPopup(p2PService, walletsSetup)) {
-//            try {
-//                final String withdrawToAddress = withdrawToTextField.getText();
-//                final Coin sendersAmount;
-//
-//                // We do not know sendersAmount if senderPaysFee is true. We repeat fee calculation after first attempt if senderPaysFee is true.
-//                Transaction feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, amountAsCoin);
-//                if (feeExcluded && feeEstimationTransaction != null) {
-//                    feeEstimationTransaction = btcWalletService.getFeeEstimationTransactionForMultipleAddresses(fromAddresses, amountAsCoin.add(feeEstimationTransaction.getFee()));
-//                }
-//                checkNotNull(feeEstimationTransaction, "feeEstimationTransaction must not be null");
-//
-//                Coin dust = btcWalletService.getDust(feeEstimationTransaction);
-//                Coin fee = feeEstimationTransaction.getFee().add(dust);
-//                Coin receiverAmount;
-//                // amountAsCoin is what the user typed into the withdrawal field.
-//                // this can be interpreted as either the senders amount or receivers amount depending
-//                // on a radio button "fee excluded / fee included".
-//                // therefore we calculate the actual sendersAmount and receiverAmount as follows:
-//                if (feeExcluded) {
-//                    receiverAmount = amountAsCoin;
-//                    sendersAmount = receiverAmount.add(fee);
-//                } else {
-//                    sendersAmount = amountAsCoin.add(dust); // sendersAmount bumped up to UTXO size when dust is in play
-//                    receiverAmount = sendersAmount.subtract(fee);
-//                }
-//                if (dust.isPositive()) {
-//                    log.info("Dust output ({} satoshi) was detected, the dust amount has been added to the fee (was {}, now {})",
-//                            dust.value,
-//                            feeEstimationTransaction.getFee(),
-//                            fee.value);
-//                }
-//
-//                if (areInputsValid(sendersAmount)) {
-//                    int txVsize = feeEstimationTransaction.getVsize();
-//                    log.info("Fee for tx with size {}: {} " + Res.getBaseCurrencyCode() + "", txVsize, fee.toPlainString());
-//
-//                    if (receiverAmount.isPositive()) {
-//                        double vkb = txVsize / 1000d;
-//
-//                        String messageText = Res.get("shared.sendFundsDetailsWithFee",
-//                                formatter.formatCoinWithCode(sendersAmount),
-//                                withdrawFromTextField.getText(),
-//                                withdrawToAddress,
-//                                formatter.formatCoinWithCode(fee),
-//                                Double.parseDouble(transactionFeeInputTextField.getText()),
-//                                vkb,
-//                                formatter.formatCoinWithCode(receiverAmount));
-//                        if (dust.isPositive()) {
-//                            messageText = Res.get("shared.sendFundsDetailsDust",
-//                                    dust.value, dust.value > 1 ? "s" : "")
-//                                    + messageText;
-//                        }
-//
-//                        new Popup().headLine(Res.get("funds.withdrawal.confirmWithdrawalRequest"))
-//                                .confirmation(messageText)
-//                                .actionButtonText(Res.get("shared.yes"))
-//                                .onAction(() -> doWithdraw(sendersAmount, fee, new FutureCallback<>() {
-//                                    @Override
-//                                    public void onSuccess(@javax.annotation.Nullable Transaction transaction) {
-//                                        if (transaction != null) {
-//                                            String key = "showTransactionSent";
-//                                            if (DontShowAgainLookup.showAgain(key)) {
-//                                                new TxDetails(transaction.getTxId().toString(), withdrawToAddress, formatter.formatCoinWithCode(sendersAmount))
-//                                                        .dontShowAgainId(key)
-//                                                        .show();
-//                                            }
-//                                            log.debug("onWithdraw onSuccess tx ID:{}", transaction.getTxId().toString());
-//                                        } else {
-//                                            log.error("onWithdraw transaction is null");
-//                                        }
-//
-//                                        List<Trade> trades = new ArrayList<>(tradeManager.getObservableList());
-//                                        trades.stream()
-//                                                .filter(Trade::isPayoutPublished)
-//                                                .forEach(trade -> btcWalletService.getAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT)
-//                                                        .ifPresent(addressEntry -> {
-//                                                            if (btcWalletService.getBalanceForAddress(addressEntry.getAddress()).isZero())
-//                                                                tradeManager.onTradeCompleted(trade);
-//                                                        }));
-//                                    }
-//
-//                                    @Override
-//                                    public void onFailure(@NotNull Throwable t) {
-//                                        log.error("onWithdraw onFailure");
-//                                    }
-//                                }))
-//                                .closeButtonText(Res.get("shared.cancel"))
-//                                .show();
-//                    } else {
-//                        new Popup().warning(Res.get("portfolio.pending.step5_buyer.amountTooLow")).show();
-//                    }
-//                }
-//            } catch (InsufficientFundsException e) {
-//                new Popup().warning(Res.get("funds.withdrawal.warn.amountExceeds") + "\n\nError message:\n" + e.getMessage()).show();
-//            } catch (Throwable e) {
-//                e.printStackTrace();
-//                log.error(e.toString());
-//                new Popup().warning(e.toString()).show();
-//            }
-//        }
+        if (GUIUtil.isReadyForTxBroadcastOrShowPopup(p2PService, xmrWalletService.getConnectionsService())) {
+            try {
+
+                // get withdraw address
+                final String withdrawToAddress = withdrawToTextField.getText();
+
+                // get receiver amount
+                Coin receiverAmount = amountAsCoin;
+                if (!receiverAmount.isPositive()) throw new RuntimeException(Res.get("portfolio.pending.step5_buyer.amountTooLow"));
+
+                // create tx
+                MoneroTxWallet tx = xmrWalletService.getWallet().createTx(new MoneroTxConfig()
+                        .setAccountIndex(0)
+                        .setAmount(ParsingUtils.coinToAtomicUnits(receiverAmount)) // TODO: rename to centinerosToAtomicUnits()?
+                        .setAddress(withdrawToAddress));
+
+                // create confirmation message
+                Coin fee = ParsingUtils.atomicUnitsToCoin(tx.getFee());
+                Coin sendersAmount = receiverAmount.add(fee);
+                String messageText = Res.get("shared.sendFundsDetailsWithFee",
+                        formatter.formatCoinWithCode(sendersAmount),
+                        withdrawFromTextField.getText(),
+                        withdrawToAddress,
+                        formatter.formatCoinWithCode(fee),
+                        formatter.formatCoinWithCode(receiverAmount));
+
+                // popup confirmation message
+                new Popup().headLine(Res.get("funds.withdrawal.confirmWithdrawalRequest"))
+                        .confirmation(messageText)
+                        .actionButtonText(Res.get("shared.yes"))
+                        .onAction(() -> {
+                            
+                            // relay tx
+                            try {
+                                xmrWalletService.getWallet().relayTx(tx);
+                                String key = "showTransactionSent";
+                                if (DontShowAgainLookup.showAgain(key)) {
+                                    new TxDetails(tx.getHash(), withdrawToAddress, formatter.formatCoinWithCode(sendersAmount))
+                                            .dontShowAgainId(key)
+                                            .show();
+                                }
+                                log.debug("onWithdraw onSuccess tx ID:{}", tx.getHash());
+                                
+                                List<Trade> trades = new ArrayList<>(tradeManager.getObservableList());
+                                trades.stream()
+                                        .filter(Trade::isPayoutPublished)
+                                        .forEach(trade -> xmrWalletService.getAddressEntry(trade.getId(), XmrAddressEntry.Context.TRADE_PAYOUT)
+                                                .ifPresent(addressEntry -> {
+                                                    if (xmrWalletService.getBalanceForAddress(addressEntry.getAddressString()).isZero())
+                                                        tradeManager.onTradeCompleted(trade);
+                                                }));
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        })
+                        .closeButtonText(Res.get("shared.cancel"))
+                        .show();
+            } catch (Throwable e) {
+                if (e.getMessage().contains("enough")) new Popup().warning(Res.get("funds.withdrawal.warn.amountExceeds") + "\n\nError message:\n" + e.getMessage()).show();
+                else {
+                    e.printStackTrace();
+                    log.error(e.toString());
+                    new Popup().warning(e.toString()).show();
+                }
+            }
+        }
     }
 
     private void selectForWithdrawal(WithdrawalListItem item) {
@@ -484,10 +359,6 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         else
             selectedItems.remove(item);
 
-        fromAddresses = selectedItems.stream()
-                .map(WithdrawalListItem::getAddressString)
-                .collect(Collectors.toSet());
-
         if (!selectedItems.isEmpty()) {
             totalAvailableAmountOfSelectedItems = Coin.valueOf(selectedItems.stream().mapToLong(e -> e.getBalance().getValue()).sum());
             if (totalAvailableAmountOfSelectedItems.isPositive()) {
@@ -533,7 +404,6 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
     ///////////////////////////////////////////////////////////////////////////////////////////
 
     private void updateList() {
-        //throw new RuntimeException("WithdrawalView.updateList() needs updated to use XMR");
         observableList.forEach(WithdrawalListItem::cleanup);
         observableList.setAll(xmrWalletService.getAddressEntriesForAvailableBalanceStream()
                 .map(addressEntry -> new WithdrawalListItem(addressEntry, xmrWalletService, formatter))
@@ -542,51 +412,6 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         updateInputSelection();
     }
 
-    private void doWithdraw(Coin amount, Coin fee, FutureCallback<Transaction> callback) {
-        throw new RuntimeException("WithdrawalView.doWithdraw() not updated to XMR");
-//        if (xmrWalletService.isEncrypted()) {
-//            UserThread.runAfter(() -> walletPasswordWindow.onAesKey(aesKey ->
-//                    sendFunds(amount, fee, aesKey, callback))
-//                    .show(), 300, TimeUnit.MILLISECONDS);
-//        } else {
-//            sendFunds(amount, fee, null, callback);
-//        }
-    }
-
-    private void sendFunds(Coin amount, Coin fee, KeyParameter aesKey, FutureCallback<Transaction> callback) {
-        throw new RuntimeException("WithdrawalView.sendFunds() not updated to XMR");
-//        try {
-//            String memo = withdrawMemoTextField.getText();
-//            if (memo.isEmpty()) {
-//                memo = null;
-//            }
-//            Transaction transaction = btcWalletService.sendFundsForMultipleAddresses(fromAddresses,
-//                    withdrawToTextField.getText(),
-//                    amount,
-//                    fee,
-//                    null,
-//                    aesKey,
-//                    memo,
-//                    callback);
-//
-//            reset();
-//            updateList();
-//        } catch (AddressFormatException e) {
-//            new Popup().warning(Res.get("validation.btc.invalidAddress")).show();
-//        } catch (Wallet.DustySendRequested e) {
-//            new Popup().warning(Res.get("validation.amountBelowDust",
-//                    formatter.formatCoinWithCode(Restrictions.getMinNonDustOutput()))).show();
-//        } catch (AddressEntryException e) {
-//            new Popup().error(e.getMessage()).show();
-//        } catch (InsufficientMoneyException e) {
-//            log.warn(e.getMessage());
-//            new Popup().warning(Res.get("funds.withdrawal.notEnoughFunds") + "\n\nError message:\n" + e.getMessage()).show();
-//        } catch (Throwable e) {
-//            log.warn(e.toString());
-//            new Popup().warning(e.toString()).show();
-//        }
-    }
-
     private void reset() {
         withdrawFromTextField.setText("");
         withdrawFromTextField.setPromptText(Res.get("funds.withdrawal.selectAddress"));
@@ -603,37 +428,10 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
         withdrawMemoTextField.setText("");
         withdrawMemoTextField.setPromptText(Res.get("funds.withdrawal.memo"));
 
-        transactionFeeInputTextField.setText("");
-        transactionFeeInputTextField.setPromptText(Res.get("funds.withdrawal.useCustomFeeValueInfo"));
-
         selectedItems.clear();
         tableView.getSelectionModel().clearSelection();
     }
 
-    private boolean areInputsValid(Coin sendersAmount) {
-        if (!sendersAmount.isPositive()) {
-            new Popup().warning(Res.get("validation.negative")).show();
-            return false;
-        }
-
-        if (!btcAddressValidator.validate(withdrawToTextField.getText()).isValid) {
-            new Popup().warning(Res.get("validation.btc.invalidAddress")).show();
-            return false;
-        }
-        if (!totalAvailableAmountOfSelectedItems.isPositive()) {
-            new Popup().warning(Res.get("funds.withdrawal.warn.noSourceAddressSelected")).show();
-            return false;
-        }
-
-        if (sendersAmount.compareTo(totalAvailableAmountOfSelectedItems) > 0) {
-            new Popup().warning(Res.get("funds.withdrawal.warn.amountExceeds")).show();
-            return false;
-        }
-
-        return true;
-    }
-
-
     ///////////////////////////////////////////////////////////////////////////////////////////
     // ColumnCellFactories
     ///////////////////////////////////////////////////////////////////////////////////////////
diff --git a/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java b/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java
index 5b6df5af..c1c627f0 100644
--- a/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java
+++ b/desktop/src/main/java/bisq/desktop/main/presentation/MarketPricePresentation.java
@@ -21,7 +21,7 @@ import bisq.desktop.components.TxIdTextField;
 import bisq.desktop.main.shared.PriceFeedComboBoxItem;
 import bisq.desktop.util.GUIUtil;
 
-import bisq.core.btc.wallet.BtcWalletService;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.CurrencyUtil;
 import bisq.core.locale.Res;
 import bisq.core.locale.TradeCurrency;
@@ -86,7 +86,7 @@ public class MarketPricePresentation {
     ///////////////////////////////////////////////////////////////////////////////////////////
 
     @Inject
-    public MarketPricePresentation(BtcWalletService btcWalletService,
+    public MarketPricePresentation(XmrWalletService xmrWalletService,
                                    PriceFeedService priceFeedService,
                                    Preferences preferences,
                                    FeeService feeService) {
@@ -96,7 +96,7 @@ public class MarketPricePresentation {
         TxIdTextField.setPreferences(preferences);
 
         // TODO
-        TxIdTextField.setWalletService(btcWalletService);
+        TxIdTextField.setXmrWalletService(xmrWalletService);
 
         GUIUtil.setFeeService(feeService);
     }
diff --git a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java
index 79cea95d..229f53fb 100644
--- a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java
+++ b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java
@@ -1047,11 +1047,12 @@ public class FormBuilder {
                                                                           String checkBoxTitle,
                                                                           double top) {
         Button button = new AutoTooltipButton(buttonTitle);
-        CheckBox checkBox = new AutoTooltipCheckBox(checkBoxTitle);
+        CheckBox checkBox = checkBoxTitle == null ? null : new AutoTooltipCheckBox(checkBoxTitle);
 
         HBox hBox = new HBox(20);
         hBox.setAlignment(Pos.CENTER_LEFT);
-        hBox.getChildren().addAll(button, checkBox);
+        hBox.getChildren().add(button);
+        if (checkBox != null) hBox.getChildren().add(button);
         GridPane.setRowIndex(hBox, rowIndex);
         hBox.setPadding(new Insets(top, 0, 0, 0));
         gridPane.getChildren().add(hBox);
diff --git a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java
index 10b1be3f..bf5ad296 100644
--- a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java
+++ b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java
@@ -32,6 +32,7 @@ import bisq.core.account.witness.AccountAgeWitness;
 import bisq.core.account.witness.AccountAgeWitnessService;
 import bisq.core.api.CoreMoneroConnectionsService;
 import bisq.core.app.HavenoSetup;
+import bisq.core.btc.wallet.XmrWalletService;
 import bisq.core.locale.Country;
 import bisq.core.locale.CountryUtil;
 import bisq.core.locale.CurrencyUtil;
@@ -134,7 +135,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
 import lombok.extern.slf4j.Slf4j;
-
+import monero.wallet.model.MoneroTxWallet;
 import org.jetbrains.annotations.NotNull;
 
 import javax.annotation.Nullable;
@@ -566,34 +567,28 @@ public class GUIUtil {
         };
     }
 
-    public static void updateConfidence(TransactionConfidence confidence,
+    public static void updateConfidence(MoneroTxWallet tx,
                                         Tooltip tooltip,
                                         TxConfidenceIndicator txConfidenceIndicator) {
-        if (confidence != null) {
-            switch (confidence.getConfidenceType()) {
-                case UNKNOWN:
-                    tooltip.setText(Res.get("confidence.unknown"));
-                    txConfidenceIndicator.setProgress(0);
-                    break;
-                case PENDING:
-                    tooltip.setText(Res.get("confidence.seen", confidence.numBroadcastPeers()));
-                    txConfidenceIndicator.setProgress(-1.0);
-                    break;
-                case BUILDING:
-                    tooltip.setText(Res.get("confidence.confirmed", confidence.getDepthInBlocks()));
-                    txConfidenceIndicator.setProgress(Math.min(1, confidence.getDepthInBlocks() / 6.0));
-                    break;
-                case DEAD:
-                    tooltip.setText(Res.get("confidence.invalid"));
-                    txConfidenceIndicator.setProgress(0);
-                    break;
+        if (tx != null) {
+            if (!tx.isRelayed()) {
+                tooltip.setText(Res.get("confidence.unknown"));
+                txConfidenceIndicator.setProgress(0);
+            } else if (tx.isFailed()) {
+                tooltip.setText(Res.get("confidence.invalid"));
+                txConfidenceIndicator.setProgress(0);
+            } else if (tx.isConfirmed()) {
+                tooltip.setText(Res.get("confidence.confirmed", tx.getNumConfirmations()));
+                txConfidenceIndicator.setProgress(Math.min(1, tx.getNumConfirmations() / (double) XmrWalletService.NUM_BLOCKS_UNLOCK));
+            } else {
+                tooltip.setText(Res.get("confidence.seen", 0)); // TODO: replace with numBroadcastPeers
+                txConfidenceIndicator.setProgress(-1.0);
             }
 
             txConfidenceIndicator.setPrefSize(24, 24);
         }
     }
 
-
     public static void openWebPage(String target) {
         openWebPage(target, true, null);
     }