preparescript: Add WALLET_ENCRYPTION_PWD env var.

Removed unnecessary START_DAEMONS env var.
Remove all cached addresses from the basicswap db for a wallet after reseeding.
Check that addresses retreived from the db are owned by teh wallet before they're used/displayed
2024-05-20_merge
tecnovert 2 years ago
parent aabf865873
commit 0f7df9e5f1
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
  1. 67
      basicswap/basicswap.py
  2. 11
      basicswap/interface/btc.py
  3. 4
      basicswap/interface/firo.py
  4. 8
      basicswap/interface/xmr.py
  5. 5
      basicswap/js_server.py
  6. 8
      basicswap/templates/wallet.html
  7. 4
      basicswap/templates/wallets.html
  8. 8
      basicswap/ui/page_wallet.py
  9. 14
      basicswap/ui/util.py
  10. 100
      bin/basicswap_prepare.py
  11. 10
      bin/basicswap_run.py
  12. 1
      doc/tor.md

@ -656,7 +656,11 @@ class BasicSwap(BaseApp):
self.log.error('Sanity checks failed: %s', str(e)) self.log.error('Sanity checks failed: %s', str(e))
elif c == Coins.XMR: elif c == Coins.XMR:
ci.ensureWalletExists() try:
ci.ensureWalletExists()
except Exception as e:
self.log.warning('Can\'t open XMR wallet, could be locked.')
continue
self.checkWalletSeed(c) self.checkWalletSeed(c)
@ -740,7 +744,7 @@ class BasicSwap(BaseApp):
yield c yield c
def changeWalletPasswords(self, old_password, new_password): def changeWalletPasswords(self, old_password, new_password):
# Only the main wallet password is changed for monero, avoid issues by preventing until active swaps are complete
if len(self.swaps_in_progress) > 0: if len(self.swaps_in_progress) > 0:
raise ValueError('Can\'t change passwords while swaps are in progress') raise ValueError('Can\'t change passwords while swaps are in progress')
@ -767,6 +771,7 @@ class BasicSwap(BaseApp):
if coin_type == Coins.PART: if coin_type == Coins.PART:
return return
ci = self.ci(coin_type) ci = self.ci(coin_type)
db_key_coin_name = ci.coin_name().lower()
self.log.info('Initialising {} wallet.'.format(ci.coin_name())) self.log.info('Initialising {} wallet.'.format(ci.coin_name()))
if coin_type == Coins.XMR: if coin_type == Coins.XMR:
@ -775,7 +780,7 @@ class BasicSwap(BaseApp):
ci.initialiseWallet(key_view, key_spend) ci.initialiseWallet(key_view, key_spend)
root_address = ci.getAddressFromKeys(key_view, key_spend) root_address = ci.getAddressFromKeys(key_view, key_spend)
key_str = 'main_wallet_addr_' + ci.coin_name().lower() key_str = 'main_wallet_addr_' + db_key_coin_name
self.setStringKV(key_str, root_address) self.setStringKV(key_str, root_address)
return return
@ -789,9 +794,23 @@ class BasicSwap(BaseApp):
self.log.error('initialiseWallet failed: {}'.format(str(e))) self.log.error('initialiseWallet failed: {}'.format(str(e)))
if raise_errors: if raise_errors:
raise e raise e
return
key_str = 'main_wallet_seedid_' + ci.coin_name().lower() try:
self.setStringKV(key_str, root_hash.hex()) session = self.openSession()
key_str = 'main_wallet_seedid_' + db_key_coin_name
self.setStringKV(key_str, root_hash.hex(), session)
# Clear any saved addresses
self.clearStringKV('receive_addr_' + db_key_coin_name, session)
self.clearStringKV('stealth_addr_' + db_key_coin_name, session)
coin_id = int(coin_type)
info_type = 1 # wallet
query_str = f'DELETE FROM wallets WHERE coin_id = {coin_id} AND balance_type = {info_type}'
session.execute(query_str)
finally:
self.closeSession(session)
def updateIdentityBidState(self, session, address, bid): def updateIdentityBidState(self, session, address, bid):
identity_stats = session.query(KnownIdentity).filter_by(address=address).first() identity_stats = session.query(KnownIdentity).filter_by(address=address).first()
@ -831,20 +850,18 @@ class BasicSwap(BaseApp):
session.remove() session.remove()
self.mxDB.release() self.mxDB.release()
def setStringKV(self, str_key, str_val): def setStringKV(self, str_key, str_val, session=None):
with self.mxDB: try:
try: use_session = self.openSession(session)
session = scoped_session(self.session_factory) kv = use_session.query(DBKVString).filter_by(key=str_key).first()
kv = session.query(DBKVString).filter_by(key=str_key).first() if not kv:
if not kv: kv = DBKVString(key=str_key, value=str_val)
kv = DBKVString(key=str_key, value=str_val) else:
else: kv.value = str_val
kv.value = str_val use_session.add(kv)
session.add(kv) finally:
session.commit() if session is None:
finally: self.closeSession(use_session)
session.close()
session.remove()
def getStringKV(self, str_key): def getStringKV(self, str_key):
self.mxDB.acquire() self.mxDB.acquire()
@ -859,6 +876,16 @@ class BasicSwap(BaseApp):
session.remove() session.remove()
self.mxDB.release() self.mxDB.release()
def clearStringKV(self, str_key, str_val):
with self.mxDB:
try:
session = scoped_session(self.session_factory)
session.execute('DELETE FROM kv_string WHERE key = "{}" '.format(str_key))
session.commit()
finally:
session.close()
session.remove()
def activateBid(self, session, bid): def activateBid(self, session, bid):
if bid.bid_id in self.swaps_in_progress: if bid.bid_id in self.swaps_in_progress:
self.log.debug('Bid %s is already in progress', bid.bid_id.hex()) self.log.debug('Bid %s is already in progress', bid.bid_id.hex())
@ -1442,6 +1469,7 @@ class BasicSwap(BaseApp):
record.bid_id = bid_id record.bid_id = bid_id
record.tx_type = tx_type record.tx_type = tx_type
addr = record.addr addr = record.addr
ensure(self.ci(coin_type).isAddressMine(addr), 'Pool address not owned by wallet!')
session.add(record) session.add(record)
session.commit() session.commit()
finally: finally:
@ -1539,6 +1567,7 @@ class BasicSwap(BaseApp):
if expect_address is None: if expect_address is None:
self.log.warning('Can\'t find expected main wallet address for coin {}'.format(ci.coin_name())) self.log.warning('Can\'t find expected main wallet address for coin {}'.format(ci.coin_name()))
return False return False
ci._have_checked_seed = True
if expect_address == ci.getMainWalletAddress(): if expect_address == ci.getMainWalletAddress():
ci.setWalletSeedWarning(False) ci.setWalletSeedWarning(False)
return True return True

@ -188,6 +188,7 @@ class BTCInterface(CoinInterface):
self._connection_type = coin_settings['connection_type'] self._connection_type = coin_settings['connection_type']
self._sc = swap_client self._sc = swap_client
self._log = self._sc.log if self._sc and self._sc.log else logging self._log = self._sc.log if self._sc and self._sc.log else logging
self._expect_seedid_hex = None
def using_segwit(self): def using_segwit(self):
return self._use_segwit return self._use_segwit
@ -297,6 +298,7 @@ class BTCInterface(CoinInterface):
return self.rpc_callback('getwalletinfo')['hdseedid'] return self.rpc_callback('getwalletinfo')['hdseedid']
def checkExpectedSeed(self, expect_seedid): def checkExpectedSeed(self, expect_seedid):
self._expect_seedid_hex = expect_seedid
return expect_seedid == self.getWalletSeedID() return expect_seedid == self.getWalletSeedID()
def getNewAddress(self, use_segwit, label='swap_receive'): def getNewAddress(self, use_segwit, label='swap_receive'):
@ -305,6 +307,15 @@ class BTCInterface(CoinInterface):
args.append('bech32') args.append('bech32')
return self.rpc_callback('getnewaddress', args) return self.rpc_callback('getnewaddress', args)
def isAddressMine(self, address):
addr_info = self.rpc_callback('getaddressinfo', [address])
return addr_info['ismine']
def checkAddressMine(self, address):
addr_info = self.rpc_callback('getaddressinfo', [address])
ensure(addr_info['ismine'], 'ismine is false')
ensure(addr_info['hdseedid'] == self._expect_seedid_hex, 'unexpected seedid')
def get_fee_rate(self, conf_target=2): def get_fee_rate(self, conf_target=2):
try: try:
fee_rate = self.rpc_callback('estimatesmartfee', [conf_target])['feerate'] fee_rate = self.rpc_callback('estimatesmartfee', [conf_target])['feerate']

@ -55,6 +55,10 @@ class FIROInterface(BTCInterface):
addr_info = self.rpc_callback('validateaddress', [address]) addr_info = self.rpc_callback('validateaddress', [address])
return addr_info['iswatchonly'] return addr_info['iswatchonly']
def isAddressMine(self, address):
addr_info = self.rpc_callback('validateaddress', [address])
return addr_info['ismine']
def getSCLockScriptAddress(self, lock_script): def getSCLockScriptAddress(self, lock_script):
lock_tx_dest = self.getScriptDest(lock_script) lock_tx_dest = self.getScriptDest(lock_script)
address = self.encodeScriptDest(lock_tx_dest) address = self.encodeScriptDest(lock_tx_dest)

@ -75,6 +75,7 @@ class XMRInterface(CoinInterface):
self._sc = swap_client self._sc = swap_client
self._log = self._sc.log if self._sc and self._sc.log else logging self._log = self._sc.log if self._sc and self._sc.log else logging
self._wallet_password = None self._wallet_password = None
self._have_checked_seed = False
def setFeePriority(self, new_priority): def setFeePriority(self, new_priority):
ensure(new_priority >= 0 and new_priority < 4, 'Invalid fee_priority value') ensure(new_priority >= 0 and new_priority < 4, 'Invalid fee_priority value')
@ -534,6 +535,13 @@ class XMRInterface(CoinInterface):
self._log.info('unlockWallet - {}'.format(self.ticker())) self._log.info('unlockWallet - {}'.format(self.ticker()))
self._wallet_password = password self._wallet_password = password
if not self._have_checked_seed:
self._sc.checkWalletSeed(self.coin_type())
def lockWallet(self): def lockWallet(self):
self._log.info('lockWallet - {}'.format(self.ticker())) self._log.info('lockWallet - {}'.format(self.ticker()))
self._wallet_password = None self._wallet_password = None
def isAddressMine(self, address):
# TODO
return True

@ -32,6 +32,7 @@ from .ui.util import (
have_data_entry, have_data_entry,
tickerToCoinId, tickerToCoinId,
listOldBidStates, listOldBidStates,
checkAddressesOwned,
) )
from .ui.page_offers import postNewOffer from .ui.page_offers import postNewOffer
from .protocols.xmr_swap_1 import recoverNoScriptTxnWithKey, getChainBSplitKey from .protocols.xmr_swap_1 import recoverNoScriptTxnWithKey, getChainBSplitKey
@ -117,8 +118,10 @@ def js_wallets(self, url_split, post_string, is_json):
rv = swap_client.getWalletInfo(coin_type) rv = swap_client.getWalletInfo(coin_type)
rv.update(swap_client.getBlockchainInfo(coin_type)) rv.update(swap_client.getBlockchainInfo(coin_type))
ci = swap_client.ci(coin_type)
checkAddressesOwned(ci, rv)
return bytes(json.dumps(rv), 'UTF-8') return bytes(json.dumps(rv), 'UTF-8')
return bytes(json.dumps(self.server.swap_client.getWalletsInfo({'ticker_key': True})), 'UTF-8') return bytes(json.dumps(swap_client.getWalletsInfo({'ticker_key': True})), 'UTF-8')
def js_offers(self, url_split, post_string, is_json, sent=False): def js_offers(self, url_split, post_string, is_json, sent=False):

@ -172,10 +172,16 @@
<td>{{ w.bootstrapping }}</td> <td>{{ w.bootstrapping }}</td>
</tr> </tr>
{% endif %} {% endif %}
{% if w.encrypted %}
<tr class="bg-white border-t hover:bg-gray-50">
<td class="py-4 px-6 bold">Locked:</td>
<td>{{ w.locked }}</td>
</tr>
{% endif %}
<tr class="bg-white border-t hover:bg-gray-50"> <tr class="bg-white border-t hover:bg-gray-50">
<td class="py-4 px-6 bold">Expected Seed:</td> <td class="py-4 px-6 bold">Expected Seed:</td>
<td>{{ w.expected_seed }}</td> <td>{{ w.expected_seed }}</td>
{% if w.expected_seed != true %} {% if w.expected_seed != true %} {# Only show addresses if wallet seed is correct #}
</tr> </tr>
</table> </table>
</div> </div>

@ -82,7 +82,9 @@
<div class="flex mb-2 justify-between items-center"> <div class="flex mb-2 justify-between items-center">
<h4 class="text-xs font-medium">Last Updated:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.lastupdated }}</span></div>{% if w.bootstrapping %} <h4 class="text-xs font-medium">Last Updated:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.lastupdated }}</span></div>{% if w.bootstrapping %}
<div class="flex mb-2 justify-between items-center"> <div class="flex mb-2 justify-between items-center">
<h4 class="text-xs font-medium">Bootstrapping:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.bootstrapping }}</span></div>{% endif %} <h4 class="text-xs font-medium">Bootstrapping:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.bootstrapping }}</span></div>{% endif %}{% if w.encrypted %}
<div class="flex mb-2 justify-between items-center">
<h4 class="text-xs font-medium">Locked:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.locked }}</span></div>{% endif %}
<div class="flex mb-2 justify-between items-center"> <div class="flex mb-2 justify-between items-center">
<h4 class="text-xs font-medium">Expected Seed:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.expected_seed }}</span></div> <h4 class="text-xs font-medium">Expected Seed:</h4> <span class="inline-block py-1 px-2 rounded-full bg-blue-100 text-xs text-black-500">{{ w.expected_seed }}</span></div>
<div class="flex justify-between mb-1 mt-10"> <span class="text-xs font-medium text-blue-700">Blockchain</span> <span class="text-xs font-medium text-blue-700">{{ w.synced }}%</span></div> <div class="flex justify-between mb-1 mt-10"> <span class="text-xs font-medium text-blue-700">Blockchain</span> <span class="text-xs font-medium text-blue-700">{{ w.synced }}%</span></div>

@ -9,6 +9,7 @@ import traceback
from .util import ( from .util import (
get_data_entry, get_data_entry,
have_data_entry, have_data_entry,
checkAddressesOwned,
) )
from basicswap.util import ( from basicswap.util import (
ensure, ensure,
@ -31,6 +32,8 @@ def format_wallet_data(ci, w):
'blocks': w.get('blocks', '?'), 'blocks': w.get('blocks', '?'),
'synced': w.get('synced', '?'), 'synced': w.get('synced', '?'),
'expected_seed': w.get('expected_seed', '?'), 'expected_seed': w.get('expected_seed', '?'),
'encrypted': w.get('encrypted', '?'),
'locked': w.get('locked', '?'),
'updating': w.get('updating', '?'), 'updating': w.get('updating', '?'),
'havedata': True, 'havedata': True,
} }
@ -55,6 +58,8 @@ def format_wallet_data(ci, w):
wf['anon_balance'] = w.get('anon_balance', '?') wf['anon_balance'] = w.get('anon_balance', '?')
if 'anon_pending' in w and float(w['anon_pending']) > 0.0: if 'anon_pending' in w and float(w['anon_pending']) > 0.0:
wf['anon_pending'] = w['anon_pending'] wf['anon_pending'] = w['anon_pending']
checkAddressesOwned(ci, wf)
return wf return wf
@ -297,7 +302,6 @@ def page_wallet(self, url_split, post_string):
if show_utxo_groups: if show_utxo_groups:
utxo_groups = '' utxo_groups = ''
unspent_by_addr = ci.getUnspentsByAddr() unspent_by_addr = ci.getUnspentsByAddr()
sorted_unspent_by_addr = sorted(unspent_by_addr.items(), key=lambda x: x[1], reverse=True) sorted_unspent_by_addr = sorted(unspent_by_addr.items(), key=lambda x: x[1], reverse=True)
@ -307,6 +311,8 @@ def page_wallet(self, url_split, post_string):
wallet_data['show_utxo_groups'] = True wallet_data['show_utxo_groups'] = True
wallet_data['utxo_groups'] = utxo_groups wallet_data['utxo_groups'] = utxo_groups
checkAddressesOwned(ci, wallet_data)
template = server.env.get_template('wallet.html') template = server.env.get_template('wallet.html')
return self.render_template(template, { return self.render_template(template, {
'messages': messages, 'messages': messages,

@ -423,3 +423,17 @@ def listAvailableCoins(swap_client, with_variants=True, split_from=False):
if split_from: if split_from:
return coins_from, coins return coins_from, coins
return coins return coins
def checkAddressesOwned(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 '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'

@ -160,8 +160,8 @@ TEST_ONION_LINK = toBool(os.getenv('TEST_ONION_LINK', 'false'))
BITCOIN_FASTSYNC_URL = os.getenv('BITCOIN_FASTSYNC_URL', 'http://utxosets.blob.core.windows.net/public/') BITCOIN_FASTSYNC_URL = os.getenv('BITCOIN_FASTSYNC_URL', 'http://utxosets.blob.core.windows.net/public/')
BITCOIN_FASTSYNC_FILE = os.getenv('BITCOIN_FASTSYNC_FILE', 'utxo-snapshot-bitcoin-mainnet-720179.tar') BITCOIN_FASTSYNC_FILE = os.getenv('BITCOIN_FASTSYNC_FILE', 'utxo-snapshot-bitcoin-mainnet-720179.tar')
# Set to false when running individual docker containers # Encrypt new wallets with this password, must match the Particl wallet password when adding coins
START_DAEMONS = toBool(os.getenv('START_DAEMONS', 'true')) WALLET_ENCRYPTION_PWD = os.getenv('WALLET_ENCRYPTION_PWD', '')
use_tor_proxy = False use_tor_proxy = False
@ -933,14 +933,49 @@ def finalise_daemon(d):
fp.close() fp.close()
def test_particl_encryption(data_dir, settings, chain, use_tor_proxy):
swap_client = None
daemons = []
daemon_args = ['-noconnect', '-nodnsseed', '-nofindpeers', '-nostaking']
if not use_tor_proxy:
# Cannot set -bind or -whitebind together with -listen=0
daemon_args.append('-nolisten')
with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp:
try:
swap_client = BasicSwap(fp, data_dir, settings, chain)
c = Coins.PART
coin_name = 'particl'
coin_settings = settings['chainclients'][coin_name]
if coin_settings['manage_daemon']:
filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '')
daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args))
swap_client.setDaemonPID(c, daemons[-1].pid)
swap_client.setCoinRunParams(c)
swap_client.createCoinInterface(c)
if swap_client.ci(c).isWalletEncrypted():
logger.info('Particl Wallet is encrypted')
if WALLET_ENCRYPTION_PWD == '':
raise ValueError('Must set WALLET_ENCRYPTION_PWD to add coin when Particl wallet is encrypted')
swap_client.ci(c).unlockWallet(WALLET_ENCRYPTION_PWD)
finally:
if swap_client:
swap_client.finalise()
del swap_client
for d in daemons:
finalise_daemon(d)
def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, chain, use_tor_proxy): def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, chain, use_tor_proxy):
swap_client = None
daemons = [] daemons = []
daemon_args = ['-noconnect', '-nodnsseed'] daemon_args = ['-noconnect', '-nodnsseed']
if not use_tor_proxy: if not use_tor_proxy:
# Cannot set -bind or -whitebind together with -listen=0 # Cannot set -bind or -whitebind together with -listen=0
daemon_args.append('-nolisten') daemon_args.append('-nolisten')
try:
with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp: with open(os.path.join(data_dir, 'basicswap.log'), 'a') as fp:
try:
swap_client = BasicSwap(fp, data_dir, settings, chain) swap_client = BasicSwap(fp, data_dir, settings, chain)
# Always start Particl, it must be running to initialise a wallet in addcoin mode # Always start Particl, it must be running to initialise a wallet in addcoin mode
@ -950,20 +985,19 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
coin_settings = settings['chainclients'][coin_name] coin_settings = settings['chainclients'][coin_name]
c = swap_client.getCoinIdFromName(coin_name) c = swap_client.getCoinIdFromName(coin_name)
if START_DAEMONS: if c == Coins.XMR:
if c == Coins.XMR: if coin_settings['manage_wallet_daemon']:
if coin_settings['manage_wallet_daemon']: daemons.append(startXmrWalletDaemon(coin_settings['datadir'], coin_settings['bindir'], 'monero-wallet-rpc'))
daemons.append(startXmrWalletDaemon(coin_settings['datadir'], coin_settings['bindir'], 'monero-wallet-rpc')) else:
else: if coin_settings['manage_daemon']:
if coin_settings['manage_daemon']: filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '')
filename = coin_name + 'd' + ('.exe' if os.name == 'nt' else '') coin_args = ['-nofindpeers', '-nostaking'] if c == Coins.PART else []
coin_args = ['-nofindpeers', '-nostaking'] if c == Coins.PART else []
if c == Coins.FIRO: if c == Coins.FIRO:
coin_args += ['-hdseed={}'.format(swap_client.getWalletKey(Coins.FIRO, 1).hex())] coin_args += ['-hdseed={}'.format(swap_client.getWalletKey(Coins.FIRO, 1).hex())]
daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args + coin_args)) daemons.append(startDaemon(coin_settings['datadir'], coin_settings['bindir'], filename, daemon_args + coin_args))
swap_client.setDaemonPID(c, daemons[-1].pid) swap_client.setDaemonPID(c, daemons[-1].pid)
swap_client.setCoinRunParams(c) swap_client.setCoinRunParams(c)
swap_client.createCoinInterface(c) swap_client.createCoinInterface(c)
@ -975,16 +1009,22 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
logger.info('Creating wallet.dat for {}.'.format(getCoinName(c))) logger.info('Creating wallet.dat for {}.'.format(getCoinName(c)))
if c == Coins.BTC: if c == Coins.BTC:
# wallet_name, wallet_name, blank, passphrase, avoid_reuse, descriptors # wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors
swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat', False, True, '', False, False]) swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat', False, True, '', False, False])
else: else:
swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat']) swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat'])
if 'particl' in with_coins and c == Coins.PART: if c == Coins.PART:
logger.info('Loading Particl mnemonic') if 'particl' in with_coins:
if particl_wallet_mnemonic is None: logger.info('Loading Particl mnemonic')
particl_wallet_mnemonic = swap_client.callcoinrpc(Coins.PART, 'mnemonic', ['new'])['mnemonic'] if particl_wallet_mnemonic is None:
swap_client.callcoinrpc(Coins.PART, 'extkeyimportmaster', [particl_wallet_mnemonic]) particl_wallet_mnemonic = swap_client.callcoinrpc(Coins.PART, 'mnemonic', ['new'])['mnemonic']
swap_client.callcoinrpc(Coins.PART, 'extkeyimportmaster', [particl_wallet_mnemonic])
if WALLET_ENCRYPTION_PWD != '':
swap_client.ci(c).changeWalletPassword('', WALLET_ENCRYPTION_PWD)
# Particl wallet must be unlocked to call getWalletKey
if WALLET_ENCRYPTION_PWD != '':
swap_client.ci(c).unlockWallet(WALLET_ENCRYPTION_PWD)
for coin_name in with_coins: for coin_name in with_coins:
c = swap_client.getCoinIdFromName(coin_name) c = swap_client.getCoinIdFromName(coin_name)
@ -992,12 +1032,15 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings,
continue continue
swap_client.waitForDaemonRPC(c) swap_client.waitForDaemonRPC(c)
swap_client.initialiseWallet(c) swap_client.initialiseWallet(c)
if WALLET_ENCRYPTION_PWD != '':
swap_client.ci(c).changeWalletPassword('', WALLET_ENCRYPTION_PWD)
swap_client.finalise() finally:
del swap_client if swap_client:
finally: swap_client.finalise()
for d in daemons: del swap_client
finalise_daemon(d) for d in daemons:
finalise_daemon(d)
if particl_wallet_mnemonic is not None: if particl_wallet_mnemonic is not None:
if particl_wallet_mnemonic: if particl_wallet_mnemonic:
@ -1369,6 +1412,9 @@ def main():
logger.info('Adding coin: %s', add_coin) logger.info('Adding coin: %s', add_coin)
settings = load_config(config_path) settings = load_config(config_path)
# Ensure Particl wallet is unencrypted or correct password is supplied
test_particl_encryption(data_dir, settings, chain, use_tor_proxy)
if add_coin in settings['chainclients']: if add_coin in settings['chainclients']:
coin_settings = settings['chainclients'][add_coin] coin_settings = settings['chainclients'][add_coin]
if coin_settings['connection_type'] == 'none' and coin_settings['manage_daemon'] is False: if coin_settings['connection_type'] == 'none' and coin_settings['manage_daemon'] is False:

@ -115,9 +115,15 @@ def ws_message_received(client, server, message):
def runClient(fp, data_dir, chain): def runClient(fp, data_dir, chain):
global swap_client global swap_client
daemons = []
pids = []
threads = []
settings_path = os.path.join(data_dir, cfg.CONFIG_FILENAME) settings_path = os.path.join(data_dir, cfg.CONFIG_FILENAME)
pids_path = os.path.join(data_dir, '.pids') pids_path = os.path.join(data_dir, '.pids')
if os.getenv('WALLET_ENCRYPTION_PWD', '') != '':
raise ValueError('Please unset the WALLET_ENCRYPTION_PWD environment variable.')
if not os.path.exists(settings_path): if not os.path.exists(settings_path):
raise ValueError('Settings file not found: ' + str(settings_path)) raise ValueError('Settings file not found: ' + str(settings_path))
@ -126,10 +132,6 @@ def runClient(fp, data_dir, chain):
swap_client = BasicSwap(fp, data_dir, settings, chain) swap_client = BasicSwap(fp, data_dir, settings, chain)
daemons = []
pids = []
threads = []
if os.path.exists(pids_path): if os.path.exists(pids_path):
with open(pids_path) as fd: with open(pids_path) as fd:
for ln in fd: for ln in fd:

@ -15,6 +15,7 @@ basicswap-prepare can be configured to download all binaries through tor and to
Docker will create directories instead of files if these don't exist. Docker will create directories instead of files if these don't exist.
mkdir -p $COINDATA_PATH/tor
touch $COINDATA_PATH/tor/torrc touch $COINDATA_PATH/tor/torrc

Loading…
Cancel
Save