diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py
index 6372e74..a285fb3 100644
--- a/basicswap/basicswap.py
+++ b/basicswap/basicswap.py
@@ -264,6 +264,8 @@ class BasicSwap(BaseApp):
self.min_sequence_lock_seconds = self.settings.get('min_sequence_lock_seconds', 60 if self.debug else (1 * 60 * 60))
self.max_sequence_lock_seconds = self.settings.get('max_sequence_lock_seconds', 96 * 60 * 60)
+ self._restrict_unknown_seed_wallets = self.settings.get('restrict_unknown_seed_wallets', True)
+
self._bid_expired_leeway = 5
self.swaps_in_progress = dict()
@@ -781,16 +783,19 @@ class BasicSwap(BaseApp):
self.log.error('Can\'t connect to %s RPC, exiting.', coin_type)
self.stopRunning(1) # systemd will try to restart the process if fail_code != 0
- def checkSynced(self, coin_from, coin_to) -> None:
+ def checkCoinsReady(self, coin_from, coin_to) -> None:
check_coins = (coin_from, coin_to)
for c in check_coins:
+ ci = self.ci(c)
+ if self._restrict_unknown_seed_wallets and not ci.knownWalletSeed():
+ raise ValueError('{} has an unexpected wallet seed and "restrict_unknown_seed_wallets" is enabled.'.format(ci.coin_name()))
if self.coin_clients[c]['connection_type'] != 'rpc':
continue
if c == Coins.XMR:
continue # TODO
- synced = round(self.ci(c).getBlockchainInfo()['verificationprogress'], 3)
+ synced = round(ci.getBlockchainInfo()['verificationprogress'], 3)
if synced < 1.0:
- raise ValueError('{} chain is still syncing, currently at {}.'.format(self.coin_clients[c]['name'], synced))
+ raise ValueError('{} chain is still syncing, currently at {}.'.format(ci.coin_name(), synced))
def isSystemUnlocked(self) -> bool:
# TODO - Check all active coins
@@ -1405,7 +1410,7 @@ class BasicSwap(BaseApp):
self.mxDB.acquire()
session = None
try:
- self.checkSynced(coin_from_t, coin_to_t)
+ self.checkCoinsReady(coin_from_t, coin_to_t)
offer_addr = self.newSMSGAddress(use_type=AddressTypes.OFFER)[0] if addr_send_from is None else addr_send_from
offer_created_at = int(time.time())
@@ -1775,6 +1780,7 @@ class BasicSwap(BaseApp):
def checkWalletSeed(self, c):
ci = self.ci(c)
if c == Coins.PART:
+ ci.setWalletSeedWarning(False) # All keys should be be derived from the Particl mnemonic
return True # TODO
if c == Coins.XMR:
expect_address = self.getCachedMainWalletAddress(ci)
@@ -1782,10 +1788,11 @@ class BasicSwap(BaseApp):
self.log.warning('Can\'t find expected main wallet address for coin {}'.format(ci.coin_name()))
return False
ci._have_checked_seed = True
- if expect_address == ci.getMainWalletAddress():
+ wallet_address: str = ci.getMainWalletAddress()
+ if expect_address == wallet_address:
ci.setWalletSeedWarning(False)
return True
- self.log.warning('Wallet for coin {} not derived from swap seed.'.format(ci.coin_name()))
+ self.log.warning('Wallet for coin {} not derived from swap seed.\n Expected {}\n Have {}'.format(ci.coin_name(), expect_address, wallet_address))
return False
expect_seedid = self.getStringKV('main_wallet_seedid_' + ci.coin_name().lower())
@@ -2058,7 +2065,7 @@ class BasicSwap(BaseApp):
ci_from = self.ci(coin_from)
ci_to = self.ci(coin_to)
- self.checkSynced(coin_from, coin_to)
+ self.checkCoinsReady(coin_from, coin_to)
amount_to = int((msg_buf.amount * bid_rate) // ci_from.COIN())
@@ -2380,7 +2387,7 @@ class BasicSwap(BaseApp):
self.validateBidValidTime(offer.swap_type, offer.coin_from, offer.coin_to, valid_for_seconds)
self.validateBidAmount(offer, amount, bid_rate)
- self.checkSynced(coin_from, coin_to)
+ self.checkCoinsReady(coin_from, coin_to)
balance_to = ci_to.getSpendableBalance()
ensure(balance_to > amount_to, '{} spendable balance is too low: {}'.format(ci_to.coin_name(), ci_to.format_amount(balance_to)))
diff --git a/basicswap/interface/btc.py b/basicswap/interface/btc.py
index ca79478..1f3b3c3 100644
--- a/basicswap/interface/btc.py
+++ b/basicswap/interface/btc.py
@@ -321,7 +321,8 @@ class BTCInterface(CoinInterface):
def checkAddressMine(self, address: str) -> None:
addr_info = self.rpc_callback('getaddressinfo', [address])
ensure(addr_info['ismine'], 'ismine is false')
- ensure(addr_info['hdseedid'] == self._expect_seedid_hex, 'unexpected seedid')
+ if self.sc._restrict_unknown_seed_wallets:
+ ensure(addr_info['hdseedid'] == self._expect_seedid_hex, 'unexpected seedid')
def get_fee_rate(self, conf_target=2):
try:
diff --git a/basicswap/js_server.py b/basicswap/js_server.py
index 09d9e29..7a5a602 100644
--- a/basicswap/js_server.py
+++ b/basicswap/js_server.py
@@ -116,14 +116,17 @@ def js_wallets(self, url_split, post_string, is_json):
value = ci.make_int(get_data_entry(post_data, 'value'))
txid_hex, new_addr = ci.createUTXO(value)
return bytes(json.dumps({'txid': txid_hex, 'address': new_addr}), 'UTF-8')
-
+ if cmd == 'reseed':
+ swap_client.reseedWallet(coin_type)
+ return bytes(json.dumps({'reseeded': True}), 'UTF-8')
raise ValueError('Unknown command')
rv = swap_client.getWalletInfo(coin_type)
rv.update(swap_client.getBlockchainInfo(coin_type))
ci = swap_client.ci(coin_type)
- checkAddressesOwned(ci, rv)
+ checkAddressesOwned(swap_client, ci, rv)
return bytes(json.dumps(rv), 'UTF-8')
+
return bytes(json.dumps(swap_client.getWalletsInfo({'ticker_key': True})), 'UTF-8')
diff --git a/basicswap/templates/wallet.html b/basicswap/templates/wallet.html
index 72f494f..d53b988 100644
--- a/basicswap/templates/wallet.html
+++ b/basicswap/templates/wallet.html
@@ -181,7 +181,7 @@
| Expected Seed: |
{{ w.expected_seed }} |
- {% if w.expected_seed != true %} {# Only show addresses if wallet seed is correct #}
+ {% if block_unknown_seeds and w.expected_seed != true %} {# Only show addresses if wallet seed is correct #}
diff --git a/basicswap/ui/page_wallet.py b/basicswap/ui/page_wallet.py
index 9093a91..127998d 100644
--- a/basicswap/ui/page_wallet.py
+++ b/basicswap/ui/page_wallet.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright (c) 2022 tecnovert
+# Copyright (c) 2022-2023 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@@ -17,12 +17,11 @@ from basicswap.util import (
)
from basicswap.chainparams import (
Coins,
- chainparams,
getCoinIdFromTicker,
)
-def format_wallet_data(ci, w):
+def format_wallet_data(swap_client, ci, w):
wf = {
'name': ci.coin_name(),
'version': w.get('version', '?'),
@@ -59,7 +58,7 @@ def format_wallet_data(ci, w):
if 'anon_pending' in w and float(w['anon_pending']) > 0.0:
wf['anon_pending'] = w['anon_pending']
- checkAddressesOwned(ci, wf)
+ checkAddressesOwned(swap_client, ci, wf)
return wf
@@ -69,65 +68,8 @@ def page_wallets(self, url_split, post_string):
swap_client.checkSystemStatus()
summary = swap_client.getSummary()
- page_data = {}
messages = []
err_messages = []
- form_data = self.checkForm(post_string, 'wallets', err_messages)
- if form_data:
- for c in Coins:
- if c not in chainparams:
- continue
- cid = str(int(c))
-
- if bytes('newaddr_' + cid, 'utf-8') in form_data:
- swap_client.cacheNewAddressForCoin(c)
- elif bytes('reseed_' + cid, 'utf-8') in form_data:
- try:
- swap_client.reseedWallet(c)
- messages.append('Reseed complete ' + str(c))
- except Exception as ex:
- err_messages.append('Reseed failed ' + str(ex))
- swap_client.updateWalletsInfo(True, c)
- elif bytes('withdraw_' + cid, 'utf-8') in form_data:
- try:
- value = form_data[bytes('amt_' + cid, 'utf-8')][0].decode('utf-8')
- page_data['wd_value_' + cid] = value
- except Exception as e:
- err_messages.append('Missing value')
- try:
- address = form_data[bytes('to_' + cid, 'utf-8')][0].decode('utf-8')
- page_data['wd_address_' + cid] = address
- except Exception as e:
- err_messages.append('Missing address')
-
- subfee = True if bytes('subfee_' + cid, 'utf-8') in form_data else False
- page_data['wd_subfee_' + cid] = subfee
-
- if c == Coins.PART:
- try:
- type_from = form_data[bytes('withdraw_type_from_' + cid, 'utf-8')][0].decode('utf-8')
- type_to = form_data[bytes('withdraw_type_to_' + cid, 'utf-8')][0].decode('utf-8')
- page_data['wd_type_from_' + cid] = type_from
- page_data['wd_type_to_' + cid] = type_to
- except Exception as e:
- err_messages.append('Missing type')
-
- if len(messages) == 0:
- ci = swap_client.ci(c)
- ticker = ci.ticker()
- if c == Coins.PART:
- try:
- txid = swap_client.withdrawParticl(type_from, type_to, value, address, subfee)
- messages.append('Withdrew {} {} ({} to {}) to address {}
In txid: {}'.format(value, ticker, type_from, type_to, address, txid))
- except Exception as e:
- err_messages.append(str(e))
- else:
- try:
- txid = swap_client.withdrawCoin(c, value, address, subfee)
- messages.append('Withdrew {} {} to address {}
In txid: {}'.format(value, ticker, address, txid))
- except Exception as e:
- err_messages.append(str(e))
- swap_client.updateWalletsInfo(True, c)
swap_client.updateWalletsInfo()
wallets = swap_client.getCachedWalletsInfo()
@@ -153,7 +95,7 @@ def page_wallets(self, url_split, post_string):
continue
ci = swap_client.ci(k)
- wf = format_wallet_data(ci, w)
+ wf = format_wallet_data(swap_client, ci, w)
wallets_formatted.append(wf)
@@ -274,7 +216,7 @@ def page_wallet(self, url_split, post_string):
ci = swap_client.ci(k)
cid = str(int(coin_id))
- wallet_data = format_wallet_data(ci, w)
+ wallet_data = format_wallet_data(swap_client, ci, w)
fee_rate, fee_src = swap_client.getFeeRateForCoin(k)
est_fee = swap_client.estimateWithdrawFee(k, fee_rate)
@@ -311,7 +253,7 @@ def page_wallet(self, url_split, post_string):
wallet_data['show_utxo_groups'] = True
wallet_data['utxo_groups'] = utxo_groups
- checkAddressesOwned(ci, wallet_data)
+ checkAddressesOwned(swap_client, ci, wallet_data)
template = server.env.get_template('wallet.html')
return self.render_template(template, {
@@ -319,4 +261,5 @@ def page_wallet(self, url_split, post_string):
'err_messages': err_messages,
'w': wallet_data,
'summary': summary,
+ 'block_unknown_seeds': swap_client._restrict_unknown_seed_wallets,
})
diff --git a/basicswap/ui/util.py b/basicswap/ui/util.py
index 9a11bb5..e676f56 100644
--- a/basicswap/ui/util.py
+++ b/basicswap/ui/util.py
@@ -429,15 +429,20 @@ def listAvailableCoins(swap_client, with_variants=True, split_from=False):
return coins
-def checkAddressesOwned(ci, wallet_info):
+def checkAddressesOwned(swap_client, ci, wallet_info):
if 'stealth_address' in wallet_info:
- if wallet_info['stealth_address'] != '?' and \
- not ci.isAddressMine(wallet_info['stealth_address']):
- ci._log.error('Unowned stealth address: {}'.format(wallet_info['stealth_address']))
- wallet_info['stealth_address'] = 'Error: unowned address'
+
+ if wallet_info['stealth_address'] != '?':
+ if not ci.isAddressMine(wallet_info['stealth_address']):
+ ci._log.error('Unowned stealth address: {}'.format(wallet_info['stealth_address']))
+ wallet_info['stealth_address'] = 'Error: unowned address'
+ elif swap_client._restrict_unknown_seed_wallets and not ci.knownWalletSeed():
+ wallet_info['stealth_address'] = 'WARNING: Unknown wallet seed'
if 'deposit_address' in wallet_info:
- if wallet_info['deposit_address'] != 'Refresh necessary' and \
- not ci.isAddressMine(wallet_info['deposit_address']):
- ci._log.error('Unowned deposit address: {}'.format(wallet_info['deposit_address']))
- wallet_info['deposit_address'] = 'Error: unowned address'
+ if wallet_info['deposit_address'] != 'Refresh necessary':
+ if not ci.isAddressMine(wallet_info['deposit_address']):
+ ci._log.error('Unowned deposit address: {}'.format(wallet_info['deposit_address']))
+ wallet_info['deposit_address'] = 'Error: unowned address'
+ elif swap_client._restrict_unknown_seed_wallets and not ci.knownWalletSeed():
+ wallet_info['deposit_address'] = 'WARNING: Unknown wallet seed'
diff --git a/doc/release-notes.md b/doc/release-notes.md
index 29ab2fb..4a4216f 100644
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -21,6 +21,8 @@
- api: getcoinseed shows seed id.
- ui: Can edit automation strategy data.
- ui: Fix pagination clearing filters
+- Added restrict_unknown_seed_wallets option.
+ - Set to false to disable unknown seed warnings.
0.0.54
diff --git a/tests/basicswap/extended/test_dash.py b/tests/basicswap/extended/test_dash.py
index 34ef9e6..1498a81 100644
--- a/tests/basicswap/extended/test_dash.py
+++ b/tests/basicswap/extended/test_dash.py
@@ -203,7 +203,8 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
'min_delay_event_short': 1,
'max_delay_event_short': 3,
'min_delay_retry': 2,
- 'max_delay_retry': 10
+ 'max_delay_retry': 10,
+ 'restrict_unknown_seed_wallets': False
}
with open(settings_path, 'w') as fp:
json.dump(settings, fp, indent=4)
diff --git a/tests/basicswap/extended/test_network.py b/tests/basicswap/extended/test_network.py
index c82c3a2..bd4f6b0 100644
--- a/tests/basicswap/extended/test_network.py
+++ b/tests/basicswap/extended/test_network.py
@@ -120,7 +120,8 @@ def prepare_swapclient_dir(datadir, node_id, network_key, network_pubkey):
'min_delay_event_short': 1,
'max_delay_event_short': 5,
'min_delay_retry': 2,
- 'max_delay_retry': 10
+ 'max_delay_retry': 10,
+ 'restrict_unknown_seed_wallets': False
}
with open(settings_path, 'w') as fp:
diff --git a/tests/basicswap/extended/test_nmc.py b/tests/basicswap/extended/test_nmc.py
index c4dcdb6..107b824 100644
--- a/tests/basicswap/extended/test_nmc.py
+++ b/tests/basicswap/extended/test_nmc.py
@@ -191,7 +191,8 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
},
'check_progress_seconds': 2,
'check_watched_seconds': 4,
- 'check_expired_seconds': 60
+ 'check_expired_seconds': 60,
+ 'restrict_unknown_seed_wallets': False,
}
with open(settings_path, 'w') as fp:
json.dump(settings, fp, indent=4)
diff --git a/tests/basicswap/extended/test_pivx.py b/tests/basicswap/extended/test_pivx.py
index 005bdfe..9f6d5ee 100644
--- a/tests/basicswap/extended/test_pivx.py
+++ b/tests/basicswap/extended/test_pivx.py
@@ -209,7 +209,8 @@ def prepareDir(datadir, nodeId, network_key, network_pubkey):
'min_delay_event_short': 1,
'max_delay_event_short': 3,
'min_delay_retry': 2,
- 'max_delay_retry': 10
+ 'max_delay_retry': 10,
+ 'restrict_unknown_seed_wallets': False
}
with open(settings_path, 'w') as fp:
json.dump(settings, fp, indent=4)
diff --git a/tests/basicswap/test_xmr.py b/tests/basicswap/test_xmr.py
index 9aceed6..db9807b 100644
--- a/tests/basicswap/test_xmr.py
+++ b/tests/basicswap/test_xmr.py
@@ -207,6 +207,7 @@ def prepare_swapclient_dir(datadir, node_id, network_key, network_pubkey, with_c
'min_delay_retry': 2,
'max_delay_retry': 10,
'debug_ui': True,
+ 'restrict_unknown_seed_wallets': False,
}
if Coins.XMR in with_coins: