From ef6653a8db07219a71aff8bbd0cd7b098d44310b Mon Sep 17 00:00:00 2001 From: tecnovert Date: Tue, 13 Dec 2022 00:12:28 +0200 Subject: [PATCH] coins: Encrypt wallets before importing seeds, allow BTC to start without wallet. Create BTC wallet on unlock if missing. --- basicswap/__init__.py | 2 +- basicswap/basicswap.py | 10 +++++++++- basicswap/interface/btc.py | 16 +++++++++++++++- basicswap/templates/debug.html | 2 +- bin/basicswap_prepare.py | 28 ++++++++++++++++------------ 5 files changed, 42 insertions(+), 16 deletions(-) diff --git a/basicswap/__init__.py b/basicswap/__init__.py index 8b91f10..924ead4 100644 --- a/basicswap/__init__.py +++ b/basicswap/__init__.py @@ -1,3 +1,3 @@ name = "basicswap" -__version__ = "0.11.54" +__version__ = "0.11.55" diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index 1385117..1285ee6 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -655,7 +655,12 @@ class BasicSwap(BaseApp): self.createCoinInterface(c) if self.coin_clients[c]['connection_type'] == 'rpc': - self.waitForDaemonRPC(c) + if c == Coins.BTC: + self.waitForDaemonRPC(c, with_wallet=False) + if len(self.callcoinrpc(c, 'listwallets')) >= 1: + self.waitForDaemonRPC(c) + else: + self.waitForDaemonRPC(c) ci = self.ci(c) core_version = ci.getDaemonVersion() self.log.info('%s Core version %d', ci.coin_name(), core_version) @@ -1655,6 +1660,9 @@ class BasicSwap(BaseApp): if expect_seedid is None: self.log.warning('Can\'t find expected wallet seed id for coin {}'.format(ci.coin_name())) return False + if len(ci.rpc_callback('listwallets')) < 1: + self.log.warning('Missing wallet for coin {}'.format(ci.coin_name())) + return False if ci.checkExpectedSeed(expect_seedid): ci.setWalletSeedWarning(False) return True diff --git a/basicswap/interface/btc.py b/basicswap/interface/btc.py index 19f0c8f..97bb771 100644 --- a/basicswap/interface/btc.py +++ b/basicswap/interface/btc.py @@ -299,7 +299,8 @@ class BTCInterface(CoinInterface): raise ValueError('{} wallet restore height not found.'.format(self.coin_name())) def getWalletSeedID(self) -> str: - return self.rpc_callback('getwalletinfo')['hdseedid'] + wi = self.rpc_callback('getwalletinfo') + return 'Not found' if 'hdseedid' not in wi else wi['hdseedid'] def checkExpectedSeed(self, expect_seedid) -> bool: self._expect_seedid_hex = expect_seedid @@ -1348,9 +1349,22 @@ class BTCInterface(CoinInterface): if password == '': return self._log.info('unlockWallet - {}'.format(self.ticker())) + + if self.coin_type() == Coins.BTC: + # Recreate wallet if none found + # Required when encrypting an existing btc wallet, workaround is to delete the btc wallet and recreate + wallets = self.rpc_callback('listwallets') + if len(wallets) < 1: + self._log.info('Creating wallet.dat for {}.'.format(self.coin_name())) + # wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors + self.rpc_callback('createwallet', ['wallet.dat', False, True, '', False, False]) + self.rpc_callback('encryptwallet', [password]) + # Max timeout value, ~3 years self.rpc_callback('walletpassphrase', [password, 100000000]) + self._sc.checkWalletSeed(self.coin_type()) + def lockWallet(self): self._log.info('lockWallet - {}'.format(self.ticker())) self.rpc_callback('walletlock') diff --git a/basicswap/templates/debug.html b/basicswap/templates/debug.html index e0be7e8..c8a7289 100644 --- a/basicswap/templates/debug.html +++ b/basicswap/templates/debug.html @@ -82,4 +82,4 @@ {% include 'footer.html' %} - \ No newline at end of file + diff --git a/bin/basicswap_prepare.py b/bin/basicswap_prepare.py index 201a8db..3c3c037 100755 --- a/bin/basicswap_prepare.py +++ b/bin/basicswap_prepare.py @@ -1006,6 +1006,7 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, try: swap_client = BasicSwap(fp, data_dir, settings, chain) + coins_to_create_wallets_for = (Coins.PART, Coins.BTC, Coins.LTC, Coins.PIVX) # Always start Particl, it must be running to initialise a wallet in addcoin mode # Particl must be loaded first as subsequent coins are initialised from the Particl mnemonic start_daemons = ['particl', ] + [c for c in with_coins if c != 'particl'] @@ -1030,7 +1031,7 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, swap_client.setCoinRunParams(c) swap_client.createCoinInterface(c) - if c in (Coins.PART, Coins.BTC, Coins.LTC, Coins.PIVX): + if c in coins_to_create_wallets_for: swap_client.waitForDaemonRPC(c, with_wallet=False) # Create wallet if it doesn't exist yet wallets = swap_client.callcoinrpc(c, 'listwallets') @@ -1043,17 +1044,20 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, else: swap_client.callcoinrpc(c, 'createwallet', ['wallet.dat']) - if c == Coins.PART: - if 'particl' in with_coins: - logger.info('Loading Particl mnemonic') - if particl_wallet_mnemonic is None: - 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) + ci = swap_client.ci(c) + ci.changeWalletPassword('', WALLET_ENCRYPTION_PWD) + ci.unlockWallet(WALLET_ENCRYPTION_PWD) + + if c == Coins.PART: + if 'particl' in with_coins: + logger.info('Loading Particl mnemonic') + if particl_wallet_mnemonic is None: + particl_wallet_mnemonic = swap_client.callcoinrpc(Coins.PART, 'mnemonic', ['new'])['mnemonic'] + swap_client.callcoinrpc(Coins.PART, 'extkeyimportmaster', [particl_wallet_mnemonic]) + # 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: c = swap_client.getCoinIdFromName(coin_name) @@ -1061,7 +1065,7 @@ def initialise_wallets(particl_wallet_mnemonic, with_coins, data_dir, settings, continue swap_client.waitForDaemonRPC(c) swap_client.initialiseWallet(c) - if WALLET_ENCRYPTION_PWD != '': + if WALLET_ENCRYPTION_PWD != '' and c not in coins_to_create_wallets_for: swap_client.ci(c).changeWalletPassword('', WALLET_ENCRYPTION_PWD) finally: