coins: Encrypt wallets before importing seeds, allow BTC to start without wallet.

Create BTC wallet on unlock if missing.
This commit is contained in:
tecnovert 2022-12-13 00:12:28 +02:00
parent 3f71dffe5a
commit ef6653a8db
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
5 changed files with 42 additions and 16 deletions

View File

@ -1,3 +1,3 @@
name = "basicswap"
__version__ = "0.11.54"
__version__ = "0.11.55"

View File

@ -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

View File

@ -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')

View File

@ -82,4 +82,4 @@
{% include 'footer.html' %}
</div>
</body>
</html>
</html>

View File

@ -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: