mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-05 18:38:09 +01:00
prepare: Fix addcoin with encrypted wallets.
Add workaround for Dash: sethdseed error if wallet is encrypted.
This commit is contained in:
@@ -1899,6 +1899,9 @@ def initialise_wallets(
|
|||||||
if c == Coins.PART and "particl" not in with_coins:
|
if c == Coins.PART and "particl" not in with_coins:
|
||||||
# Running addcoin with an existing particl wallet
|
# Running addcoin with an existing particl wallet
|
||||||
swap_client.waitForDaemonRPC(c, with_wallet=True)
|
swap_client.waitForDaemonRPC(c, with_wallet=True)
|
||||||
|
# Particl wallet must be unlocked to call getWalletKey
|
||||||
|
if WALLET_ENCRYPTION_PWD != "":
|
||||||
|
swap_client.ci(c).unlockWallet(WALLET_ENCRYPTION_PWD)
|
||||||
continue
|
continue
|
||||||
if c == Coins.DCR:
|
if c == Coins.DCR:
|
||||||
if coin_settings["manage_wallet_daemon"] is False:
|
if coin_settings["manage_wallet_daemon"] is False:
|
||||||
@@ -1930,11 +1933,28 @@ def initialise_wallets(
|
|||||||
logger.info(
|
logger.info(
|
||||||
f'Creating wallet "{wallet_name}" for {getCoinName(c)}.'
|
f'Creating wallet "{wallet_name}" for {getCoinName(c)}.'
|
||||||
)
|
)
|
||||||
|
use_descriptors = coin_settings.get("use_descriptors", False)
|
||||||
if c in (Coins.BTC, Coins.LTC, Coins.NMC, Coins.DOGE, Coins.DASH):
|
if c in (Coins.DASH,):
|
||||||
|
# TODO: Remove when fixed
|
||||||
|
if WALLET_ENCRYPTION_PWD != "":
|
||||||
|
logger.warning(
|
||||||
|
"Workaround for Dash sethdseed error if wallet is encrypted."
|
||||||
|
) # Errors with "AddHDChainSingle failed"
|
||||||
|
assert use_descriptors is False
|
||||||
|
swap_client.callcoinrpc(
|
||||||
|
c,
|
||||||
|
"createwallet",
|
||||||
|
[
|
||||||
|
wallet_name,
|
||||||
|
False,
|
||||||
|
True,
|
||||||
|
"",
|
||||||
|
False,
|
||||||
|
use_descriptors,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
elif c in (Coins.BTC, Coins.LTC, Coins.NMC, Coins.DOGE):
|
||||||
# wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors
|
# wallet_name, disable_private_keys, blank, passphrase, avoid_reuse, descriptors
|
||||||
|
|
||||||
use_descriptors = coin_settings.get("use_descriptors", False)
|
|
||||||
swap_client.callcoinrpc(
|
swap_client.callcoinrpc(
|
||||||
c,
|
c,
|
||||||
"createwallet",
|
"createwallet",
|
||||||
@@ -1964,7 +1984,9 @@ def initialise_wallets(
|
|||||||
use_descriptors,
|
use_descriptors,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
swap_client.ci(c).unlockWallet(WALLET_ENCRYPTION_PWD)
|
swap_client.ci(c).unlockWallet(
|
||||||
|
WALLET_ENCRYPTION_PWD, check_seed=False
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
swap_client.callcoinrpc(
|
swap_client.callcoinrpc(
|
||||||
c,
|
c,
|
||||||
@@ -1995,9 +2017,6 @@ def initialise_wallets(
|
|||||||
swap_client.callcoinrpc(
|
swap_client.callcoinrpc(
|
||||||
Coins.PART, "extkeyimportmaster", [particl_wallet_mnemonic]
|
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:
|
for coin_name in with_coins:
|
||||||
c = swap_client.getCoinIdFromName(coin_name)
|
c = swap_client.getCoinIdFromName(coin_name)
|
||||||
@@ -2010,7 +2029,9 @@ def initialise_wallets(
|
|||||||
swap_client.initialiseWallet(c, raise_errors=True)
|
swap_client.initialiseWallet(c, raise_errors=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
coins_failed_to_initialise.append((c, e))
|
coins_failed_to_initialise.append((c, e))
|
||||||
if WALLET_ENCRYPTION_PWD != "" and c not in coins_to_create_wallets_for:
|
if WALLET_ENCRYPTION_PWD != "" and (
|
||||||
|
c not in coins_to_create_wallets_for or c in (Coins.DASH,)
|
||||||
|
): # TODO: Remove DASH workaround
|
||||||
try:
|
try:
|
||||||
swap_client.ci(c).changeWalletPassword("", WALLET_ENCRYPTION_PWD)
|
swap_client.ci(c).changeWalletPassword("", WALLET_ENCRYPTION_PWD)
|
||||||
except Exception as e: # noqa: F841
|
except Exception as e: # noqa: F841
|
||||||
@@ -2026,12 +2047,12 @@ def initialise_wallets(
|
|||||||
print("")
|
print("")
|
||||||
for pair in coins_failed_to_initialise:
|
for pair in coins_failed_to_initialise:
|
||||||
c, e = pair
|
c, e = pair
|
||||||
if c in (Coins.PIVX,):
|
if c in (Coins.PIVX, Coins.BCH):
|
||||||
print(
|
print(
|
||||||
f"NOTE - Unable to initialise wallet for {getCoinName(c)}. To complete setup click 'Reseed Wallet' from the ui page once chain is synced."
|
f"NOTE - Unable to initialise wallet for {getCoinName(c)}. To complete setup click 'Reseed Wallet' from the ui page once chain is synced."
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(f"WARNING - Failed to initialise wallet for {getCoinName(c)}: {e}")
|
raise ValueError(f"Failed to initialise wallet for {getCoinName(c)}: {e}")
|
||||||
|
|
||||||
if "decred" in with_coins and WALLET_ENCRYPTION_PWD != "":
|
if "decred" in with_coins and WALLET_ENCRYPTION_PWD != "":
|
||||||
print(
|
print(
|
||||||
|
|||||||
@@ -1986,7 +1986,7 @@ class BTCInterface(Secp256k1Interface):
|
|||||||
return self.rpc_wallet("encryptwallet", [new_password])
|
return self.rpc_wallet("encryptwallet", [new_password])
|
||||||
self.rpc_wallet("walletpassphrasechange", [old_password, new_password])
|
self.rpc_wallet("walletpassphrasechange", [old_password, new_password])
|
||||||
|
|
||||||
def unlockWallet(self, password: str):
|
def unlockWallet(self, password: str, check_seed: bool = True) -> None:
|
||||||
if password == "":
|
if password == "":
|
||||||
return
|
return
|
||||||
self._log.info(f"unlockWallet - {self.ticker()}")
|
self._log.info(f"unlockWallet - {self.ticker()}")
|
||||||
@@ -2007,7 +2007,8 @@ class BTCInterface(Secp256k1Interface):
|
|||||||
|
|
||||||
# Max timeout value, ~3 years
|
# Max timeout value, ~3 years
|
||||||
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
||||||
self._sc.checkWalletSeed(self.coin_type())
|
if check_seed:
|
||||||
|
self._sc.checkWalletSeed(self.coin_type())
|
||||||
|
|
||||||
def lockWallet(self):
|
def lockWallet(self):
|
||||||
self._log.info(f"lockWallet - {self.ticker()}")
|
self._log.info(f"lockWallet - {self.ticker()}")
|
||||||
|
|||||||
@@ -111,17 +111,11 @@ class DASHInterface(BTCInterface):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def unlockWallet(self, password: str):
|
def unlockWallet(self, password: str, check_seed: bool = True) -> None:
|
||||||
super().unlockWallet(password)
|
super().unlockWallet(password, check_seed)
|
||||||
if self._wallet_v20_compatible:
|
if self._wallet_v20_compatible:
|
||||||
# Store password for initialiseWallet
|
# Store password for initialiseWallet
|
||||||
self._wallet_passphrase = password
|
self._wallet_passphrase = password
|
||||||
if not self._have_checked_seed:
|
|
||||||
try:
|
|
||||||
self._sc.checkWalletSeed(self.coin_type())
|
|
||||||
except Exception as ex:
|
|
||||||
# dumphdinfo can fail if the wallet is not initialised
|
|
||||||
self._log.debug(f"DASH checkWalletSeed failed: {ex}.")
|
|
||||||
|
|
||||||
def lockWallet(self):
|
def lockWallet(self):
|
||||||
super().lockWallet()
|
super().lockWallet()
|
||||||
|
|||||||
@@ -368,14 +368,15 @@ class DCRInterface(Secp256k1Interface):
|
|||||||
# Clear initial password
|
# Clear initial password
|
||||||
self._sc.editSettings(self.coin_name().lower(), {"wallet_pwd": ""})
|
self._sc.editSettings(self.coin_name().lower(), {"wallet_pwd": ""})
|
||||||
|
|
||||||
def unlockWallet(self, password: str):
|
def unlockWallet(self, password: str, check_seed: bool = True) -> None:
|
||||||
if password == "":
|
if password == "":
|
||||||
return
|
return
|
||||||
self._log.info("unlockWallet - {}".format(self.ticker()))
|
self._log.info("unlockWallet - {}".format(self.ticker()))
|
||||||
|
|
||||||
# Max timeout value, ~3 years
|
# Max timeout value, ~3 years
|
||||||
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
||||||
self._sc.checkWalletSeed(self.coin_type())
|
if check_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()))
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class LTCInterfaceMWEB(LTCInterface):
|
|||||||
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
||||||
self.rpc_wallet("keypoolrefill")
|
self.rpc_wallet("keypoolrefill")
|
||||||
|
|
||||||
def unlockWallet(self, password: str):
|
def unlockWallet(self, password: str, check_seed: bool = True) -> None:
|
||||||
if password == "":
|
if password == "":
|
||||||
return
|
return
|
||||||
self._log.info("unlockWallet - {}".format(self.ticker()))
|
self._log.info("unlockWallet - {}".format(self.ticker()))
|
||||||
@@ -156,5 +156,5 @@ class LTCInterfaceMWEB(LTCInterface):
|
|||||||
else:
|
else:
|
||||||
# Max timeout value, ~3 years
|
# Max timeout value, ~3 years
|
||||||
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
self.rpc_wallet("walletpassphrase", [password, 100000000])
|
||||||
|
if check_seed:
|
||||||
self._sc.checkWalletSeed(self.coin_type())
|
self._sc.checkWalletSeed(self.coin_type())
|
||||||
|
|||||||
@@ -744,11 +744,11 @@ class XMRInterface(CoinInterface):
|
|||||||
self._wallet_password = orig_password
|
self._wallet_password = orig_password
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def unlockWallet(self, password: str) -> None:
|
def unlockWallet(self, password: str, check_seed: bool = True) -> None:
|
||||||
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:
|
if check_seed and not self._have_checked_seed:
|
||||||
self._sc.checkWalletSeed(self.coin_type())
|
self._sc.checkWalletSeed(self.coin_type())
|
||||||
|
|
||||||
def lockWallet(self) -> None:
|
def lockWallet(self) -> None:
|
||||||
|
|||||||
@@ -758,20 +758,39 @@ class Test(unittest.TestCase):
|
|||||||
def test_09_initialise_wallet(self):
|
def test_09_initialise_wallet(self):
|
||||||
logging.info("---------- Test DASH initialiseWallet")
|
logging.info("---------- Test DASH initialiseWallet")
|
||||||
|
|
||||||
self.swap_clients[0].initialiseWallet(Coins.DASH, raise_errors=True)
|
test_seed = "8e54a313e6df8918df6d758fafdbf127a115175fdd2238d0e908dd8093c9ac3b"
|
||||||
assert self.swap_clients[0].checkWalletSeed(Coins.DASH) is True
|
ci = self.swap_clients[0].ci(Coins.DASH)
|
||||||
|
test_wif: str = ci.encodeKey(bytes.fromhex(test_seed))
|
||||||
|
new_wallet_name: str = random.randbytes(10).hex()
|
||||||
|
# wallet_name, wallet_name, blank, passphrase, avoid_reuse, descriptors
|
||||||
|
ci.rpc("createwallet", [new_wallet_name, False, True, "", False, False])
|
||||||
|
ci.rpc("sethdseed", [True, test_wif], wallet_override=new_wallet_name)
|
||||||
|
|
||||||
addr = dashRpc('getnewaddress "hd wallet test"')
|
test_pwd: str = "test_pwd"
|
||||||
assert addr == "ybzWYJbZEhZai8kiKkTtPFKTuDNwhpiwac"
|
ci.rpc(
|
||||||
|
"encryptwallet",
|
||||||
|
[
|
||||||
|
test_pwd,
|
||||||
|
],
|
||||||
|
wallet_override=new_wallet_name,
|
||||||
|
)
|
||||||
|
|
||||||
logging.info("Test that getcoinseed returns a mnemonic for Dash")
|
addr = ci.rpc("getnewaddress", wallet_override=new_wallet_name)
|
||||||
mnemonic = read_json_api(1800, "getcoinseed", {"coin": "DASH"})["mnemonic"]
|
# sethdseed keys are not == upgradetohd, was "ybzWYJbZEhZai8kiKkTtPFKTuDNwhpiwac"
|
||||||
new_wallet_name = random.randbytes(10).hex()
|
assert addr == "yb8DSec26MLqtuj48iELnhnDCSBBbpWJ9p"
|
||||||
dashRpc(f'createwallet "{new_wallet_name}"')
|
|
||||||
dashRpc(f'upgradetohd "{mnemonic}"', wallet=new_wallet_name)
|
new_wallet_name += "_encrypted"
|
||||||
addr_test = dashRpc("getnewaddress", wallet=new_wallet_name)
|
ci.rpc("createwallet", [new_wallet_name, False, True, test_pwd, False, False])
|
||||||
dashRpc("unloadwallet", wallet=new_wallet_name)
|
ci.rpc("walletpassphrase", [test_pwd, 1000], wallet_override=new_wallet_name)
|
||||||
assert addr_test == addr
|
# sethdseed fails on encrypted wallets!
|
||||||
|
try:
|
||||||
|
ci.rpc("sethdseed", [True, test_wif], wallet_override=new_wallet_name)
|
||||||
|
except Exception as e:
|
||||||
|
assert "AddHDChainSingle failed" in str(e)
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"sethdseed on encrypted wallets is fixed! Remove workaround in prepare.py."
|
||||||
|
)
|
||||||
|
|
||||||
def test_10_prefunded_itx(self):
|
def test_10_prefunded_itx(self):
|
||||||
logging.info("---------- Test prefunded itx offer")
|
logging.info("---------- Test prefunded itx offer")
|
||||||
|
|||||||
@@ -1187,12 +1187,12 @@ class BasicSwapTest(TestFunctions):
|
|||||||
logging.warning("Skipping test")
|
logging.warning("Skipping test")
|
||||||
return
|
return
|
||||||
|
|
||||||
test_wif = (
|
test_wif: str = (
|
||||||
self.swap_clients[0]
|
self.swap_clients[0]
|
||||||
.ci(self.test_coin_from)
|
.ci(self.test_coin_from)
|
||||||
.encodeKey(bytes.fromhex(test_seed))
|
.encodeKey(bytes.fromhex(test_seed))
|
||||||
)
|
)
|
||||||
new_wallet_name = random.randbytes(10).hex()
|
new_wallet_name: str = random.randbytes(10).hex()
|
||||||
# wallet_name, wallet_name, blank, passphrase, avoid_reuse, descriptors
|
# wallet_name, wallet_name, blank, passphrase, avoid_reuse, descriptors
|
||||||
self.callnoderpc(
|
self.callnoderpc(
|
||||||
"createwallet", [new_wallet_name, False, True, "", False, False]
|
"createwallet", [new_wallet_name, False, True, "", False, False]
|
||||||
|
|||||||
Reference in New Issue
Block a user