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
This commit is contained in:
		
							parent
							
								
									aabf865873
								
							
						
					
					
						commit
						0f7df9e5f1
					
				@ -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…
	
		Reference in New Issue
	
	Block a user