diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py
index 1a421ad..1714c96 100644
--- a/basicswap/basicswap.py
+++ b/basicswap/basicswap.py
@@ -6522,6 +6522,9 @@ class BasicSwap(BaseApp):
                 'locked': walletinfo['locked'],
             }
 
+            if 'locked_utxos' in walletinfo:
+                rv['locked_utxos'] = walletinfo['locked_utxos']
+
             if coin == Coins.PART:
                 rv['stealth_address'] = self.getCachedStealthAddressForCoin(Coins.PART)
                 rv['anon_balance'] = walletinfo['anon_balance']
diff --git a/basicswap/interface/btc.py b/basicswap/interface/btc.py
index 2b213c2..1faa1dd 100644
--- a/basicswap/interface/btc.py
+++ b/basicswap/interface/btc.py
@@ -300,6 +300,7 @@ class BTCInterface(CoinInterface):
         rv = self.rpc_wallet('getwalletinfo')
         rv['encrypted'] = 'unlocked_until' in rv
         rv['locked'] = rv.get('unlocked_until', 1) <= 0
+        rv['locked_utxos'] = len(self.rpc_wallet('listlockunspent'))
         return rv
 
     def walletRestoreHeight(self) -> int:
diff --git a/basicswap/interface/ltc.py b/basicswap/interface/ltc.py
index 4576208..6dc1ddf 100644
--- a/basicswap/interface/ltc.py
+++ b/basicswap/interface/ltc.py
@@ -33,9 +33,7 @@ class LTCInterface(BTCInterface):
         return self.rpc_wallet('sendtoaddress', params)
 
     def getWalletInfo(self):
-        rv = self.rpc_wallet('getwalletinfo')
-        rv['encrypted'] = 'unlocked_until' in rv
-        rv['locked'] = rv.get('unlocked_until', 1) <= 0
+        rv = super(LTCInterface, self).getWalletInfo()
 
         mweb_info = self.rpc_wallet_mweb('getwalletinfo')
         rv['mweb_balance'] = mweb_info['balance']
diff --git a/basicswap/js_server.py b/basicswap/js_server.py
index eb9ed5d..6ae75eb 100644
--- a/basicswap/js_server.py
+++ b/basicswap/js_server.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2020-2023 tecnovert
+# Copyright (c) 2020-2024 tecnovert
 # Distributed under the MIT software license, see the accompanying
 # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 
diff --git a/basicswap/templates/rpc.html b/basicswap/templates/rpc.html
index 2d5c861..ead82e3 100644
--- a/basicswap/templates/rpc.html
+++ b/basicswap/templates/rpc.html
@@ -121,7 +121,7 @@
         <div class="px-6">
          <div class="flex flex-wrap justify-end">
           <div class="w-full md:w-auto p-1.5 ml-2">
-           <button name="" value="Apply" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
+           <button name="apply" value="Apply" type="submit" class="flex flex-wrap justify-center w-full px-4 py-2.5 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
             <svg class="text-gray-500 w-5 h-5 mr-2" xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24">
              <g stroke-linecap="round" stroke-width="2" fill="none" stroke="#ffffff" stroke-linejoin="round">
               <polyline points=" 6,12 10,16 18,8 " stroke="#ffffff"></polyline>
@@ -160,7 +160,7 @@
            </thead>
            <tr class="opacity-100 text-gray-500 dark:text-gray-100">
             <td class="py-3 px-6">
-             <textarea class="hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0" rows="20">{{ result }}</textarea>
+             <textarea name="result" class="hover:border-blue-500 bg-gray-50 text-gray-900 appearance-none pr-10 dark:bg-gray-500 dark:text-white border border-gray-300 dark:border-gray-400 dark:text-gray-50 dark:placeholder-gray-50 text-sm rounded-lg outline-none focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 focus:ring-0" rows="20">{{ result }}</textarea>
             </td>
            </tr>
           </table>
diff --git a/basicswap/templates/wallet.html b/basicswap/templates/wallet.html
index d389d9b..b23042e 100644
--- a/basicswap/templates/wallet.html
+++ b/basicswap/templates/wallet.html
@@ -172,6 +172,12 @@
                         <td class="py-3 px-6 bold coinname-value" data-coinname="{{ w.name }}">{{ w.mweb_balance }} {{ w.ticker }} (<span class="usd-value"></span>) {% if w.mweb_pending %} <span class="inline-block py-1 px-2 rounded-full bg-green-100 text-green-500 dark:bg-gray-500 dark:text-green-500">Pending: +{{ w.mweb_pending }} {{ w.ticker }}</span>{% endif %}</td>
                       </tr>
                     {% endif %} {# / LTC #}
+                    {% if w.locked_utxos %}
+                    <tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
+                      <td class="py-3 px-6 bold">Locked Outputs:</td>
+                      <td id='locked_utxos' class="py-3 px-6">{{ w.locked_utxos }}</td>
+                    </tr>
+                    {% endif %} {# / locked_utxos #}
                     <tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
                       <td class="py-3 px-6 bold">Blocks:</td>
                       <td class="py-3 px-6">{{ w.blocks }} {% if w.known_block_count %} / {{ w.known_block_count }} {% endif %}</td>
@@ -637,4 +643,4 @@ document.addEventListener('DOMContentLoaded', () => {
 </script>
 
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/basicswap/ui/page_wallet.py b/basicswap/ui/page_wallet.py
index cfaf04e..b8f2cf3 100644
--- a/basicswap/ui/page_wallet.py
+++ b/basicswap/ui/page_wallet.py
@@ -41,6 +41,8 @@ def format_wallet_data(swap_client, ci, w):
         wf['bootstrapping'] = True
     if 'known_block_count' in w:
         wf['known_block_count'] = w['known_block_count']
+    if 'locked_utxos' in w:
+        wf['locked_utxos'] = w['locked_utxos']
 
     if 'balance' in w and 'unconfirmed' in w:
         wf['balance_all'] = float(w['balance']) + float(w['unconfirmed'])
diff --git a/tests/basicswap/selenium/test_wallets.py b/tests/basicswap/selenium/test_wallets.py
index 8f76e69..c113295 100644
--- a/tests/basicswap/selenium/test_wallets.py
+++ b/tests/basicswap/selenium/test_wallets.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2022-2023 tecnovert
+# Copyright (c) 2022-2024 tecnovert
 # Distributed under the MIT software license, see the accompanying
 # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 
@@ -10,7 +10,9 @@ import time
 
 from urllib.request import urlopen
 from selenium.webdriver.common.by import By
+from selenium.webdriver.support.select import Select
 from util import get_driver
+from basicswap.util import dumpje
 
 
 def test_wallets(driver):
@@ -72,6 +74,50 @@ def test_wallets(driver):
     e = elements[0]
     assert ('Withdrew 10 rtPART (plain to plain) to address' in e.text)
 
+    print('Locking UTXO')
+    driver.get(base_url + '/rpc')
+    el = driver.find_element(By.NAME, 'coin_type')
+    for option in el.find_elements(By.TAG_NAME, 'option'):
+        if option.text == 'Particl':
+            option.click()
+            break
+    driver.find_element(By.NAME, 'cmd').send_keys('listunspent')
+    driver.find_element(By.NAME, 'apply').click()
+    time.sleep(1)
+
+    text_value = driver.find_element(By.NAME, 'result').text
+    utxos = json.loads(text_value.split('\n', 1)[1])
+
+    lock_utxos = [{'txid': utxos[0]['txid'], 'vout': utxos[0]['vout']}]
+    driver.find_element(By.NAME, 'cmd').send_keys('lockunspent false "{}"'.format(dumpje(lock_utxos)))
+    driver.find_element(By.NAME, 'apply').click()
+
+    print('Check for locked UTXO count')
+    driver.get(base_url + '/wallet/PART')
+    found = False
+    for i in range(5):
+        try:
+            el = driver.find_element(By.ID, 'locked_utxos')
+            found = True
+            break
+        except Exception:
+            continue
+        driver.find_element(By.ID, 'refresh').click()
+        time.sleep(2)
+        found = True
+    assert (found)
+    driver.refresh()
+
+    print('Unlocking UTXO')
+    driver.get(base_url + '/rpc')
+    el = driver.find_element(By.NAME, 'coin_type')
+    for option in el.find_elements(By.TAG_NAME, 'option'):
+        if option.text == 'Particl':
+            option.click()
+            break
+    driver.find_element(By.NAME, 'cmd').send_keys('lockunspent true "{}"'.format(dumpje(lock_utxos)))
+    driver.find_element(By.NAME, 'apply').click()
+
     print('Test Passed!')
 
 
diff --git a/tests/basicswap/test_run.py b/tests/basicswap/test_run.py
index 1557dbb..57c0a99 100644
--- a/tests/basicswap/test_run.py
+++ b/tests/basicswap/test_run.py
@@ -182,6 +182,9 @@ class Test(BaseTest):
         sx_addr = read_json_api(1800, 'wallets/part/newstealthaddress')
         assert (callnoderpc(0, 'getaddressinfo', [sx_addr, ])['isstealthaddress'] is True)
 
+        rv = read_json_api(1800, 'wallets/part')
+        assert ('locked_utxos' in rv)
+
     def test_004_validateSwapType(self):
         logging.info('---------- Test validateSwapType')
 
diff --git a/tests/basicswap/test_xmr.py b/tests/basicswap/test_xmr.py
index 5a1024c..2417847 100644
--- a/tests/basicswap/test_xmr.py
+++ b/tests/basicswap/test_xmr.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 
-# Copyright (c) 2020-2023 tecnovert
+# Copyright (c) 2020-2024 tecnovert
 # Distributed under the MIT software license, see the accompanying
 # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
 
@@ -107,6 +107,7 @@ XMR_BASE_RPC_PORT = 21792
 XMR_BASE_ZMQ_PORT = 22792
 XMR_BASE_WALLET_RPC_PORT = 23792
 
+signal_event = threading.Event()  # Set if test was cancelled
 test_delay_event = threading.Event()
 RESET_TEST = make_boolean(os.getenv('RESET_TEST', 'true'))
 
@@ -255,6 +256,7 @@ def ltcCli(cmd, node_id=0):
 
 def signal_handler(sig, frame):
     logging.info('signal {} detected.'.format(sig))
+    signal_event.set()
     test_delay_event.set()
 
 
@@ -336,6 +338,8 @@ class BaseTest(unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
+        if signal_event.is_set():
+            raise ValueError('Test has been cancelled.')
         test_delay_event.clear()
         random.seed(time.time())