diff --git a/basicswap/interface/dash.py b/basicswap/interface/dash.py index 0caf04f..26b701e 100644 --- a/basicswap/interface/dash.py +++ b/basicswap/interface/dash.py @@ -25,6 +25,8 @@ class DASHInterface(BTCInterface): self._wallet_passphrase = '' self._have_checked_seed = False + self._wallet_v20_compatible = False if not swap_client else swap_client.getChainClientSettings(self.coin_type()).get('wallet_v20_compatible', False) + def decodeAddress(self, address: str) -> bytes: return decodeAddress(address)[1:] @@ -32,6 +34,33 @@ class DASHInterface(BTCInterface): hdseed: str = self.rpc_wallet('dumphdinfo')['hdseed'] return self.getSeedHash(bytes.fromhex(hdseed)).hex() + def entropyToMnemonic(self, key: bytes) -> None: + return Mnemonic('english').to_mnemonic(key) + + def initialiseWallet(self, key_bytes: bytes) -> None: + if self._wallet_v20_compatible: + self._log.warning(f'Generating wallet compatible with v20 seed.') + words = self.entropyToMnemonic(key_bytes) + mnemonic_passphrase = '' + self.rpc_wallet('upgradetohd', [words, mnemonic_passphrase, self._wallet_passphrase]) + self._have_checked_seed = False + if self._wallet_passphrase != '': + self.unlockWallet(self._wallet_passphrase) + return + + key_wif = self.encodeKey(key_bytes) + self.rpc_wallet('sethdseed', [True, key_wif]) + + def checkExpectedSeed(self, expect_seedid: str) -> bool: + self._expect_seedid_hex = expect_seedid + rv = self.rpc_wallet('dumphdinfo') + if rv['mnemonic'] != '': + entropy = Mnemonic('english').to_entropy(rv['mnemonic'].split(' ')) + entropy_hash = self.getAddressHashFromKey(entropy)[::-1].hex() + return expect_seedid == entropy_hash + else: + return expect_seedid == self.getWalletSeedID() + def withdrawCoin(self, value, addr_to, subfee): params = [addr_to, value, '', '', subfee, False, False, self._conf_target] return self.rpc_wallet('sendtoaddress', params) diff --git a/bin/basicswap_prepare.py b/bin/basicswap_prepare.py index 32c15b7..1cee49d 100755 --- a/bin/basicswap_prepare.py +++ b/bin/basicswap_prepare.py @@ -1256,6 +1256,7 @@ def printHelp(): print('--keysdirpath Speed up tests by preloading all PGP keys in directory.') print('--noreleasesizecheck If unset the size of existing core release files will be compared to their size at their download url.') print('--redownloadreleases If set core release files will be redownloaded.') + print('--dashv20compatible Generate the same DASH wallet seed as for DASH v20 - Use only when importing an existing seed.') active_coins = [] for coin_name in known_coins.keys(): @@ -1588,6 +1589,9 @@ def main(): if name == 'initwalletsonly': initwalletsonly = True continue + if name == 'dashv20compatible': + extra_opts['dash_v20_compatible'] = True + continue if len(s) == 2: if name == 'datadir': data_dir = os.path.expanduser(s[1].strip('"')) @@ -1933,6 +1937,9 @@ def main(): chainclients['monero']['walletsdir'] = os.getenv('XMR_WALLETS_DIR', chainclients['monero']['datadir']) chainclients['wownero']['walletsdir'] = os.getenv('WOW_WALLETS_DIR', chainclients['wownero']['datadir']) + if extra_opts.get('dash_v20_compatible', False): + chainclients['dash']['wallet_v20_compatible'] = True + if initwalletsonly: logger.info('Initialising wallets') settings = load_config(config_path) diff --git a/doc/coins/dash.md b/doc/coins/dash.md new file mode 100644 index 0000000..b5770b3 --- /dev/null +++ b/doc/coins/dash.md @@ -0,0 +1,14 @@ +## DASH Notes + +### Importing wallets created with DASH version <21 + + +From version 21 DASH core can use the sethdseed rpc command. +The old method to import a seed used the DASH specific upgradetohd rpc command. + + +To import a wallet created on DASH v20 use basicswap-prepare with the --dashv20compatible flag. + +Example: + + basicswap-prepare --withcoins=dash --particl_mnemonic="..." --dashv20compatible