def _read_wallet(self): self.address_bundle = [] if not os.path.isfile(self.wallet_dat_filename): return try: with open(self.wallet_dat_filename, "rb") as infile: wallet_store = qrl_pb2.WalletStore() wallet_store.ParseFromString(bytes(infile.read())) self.address_bundle = [] for a in wallet_store.wallets: tmpxmss = XMSS(config.dev.xmss_tree_height, mnemonic2bin(a.mnemonic.strip())) tmpxmss.set_index(a.xmss_index) if a.address.encode() != tmpxmss.get_address(): logger.fatal("Mnemonic and address do not match.") exit(1) self.address_bundle.append(AddressBundle(tmpxmss.get_address(), tmpxmss)) except Exception as e: logger.warning("It was not possible to open the wallet: %s", e)
def test_mnemonic3(self): long_mnemonic = "law bruise screen lunar than loft but franc strike asleep dwarf tavern dragon alarm " + \ "snack queen meadow thing far cotton add emblem strive probe zurich edge peer alight " + \ "libel won corn medal" exp_result = '7ad1e6c1083de2081221056dd8b0c142cdfa3fd053cd4ae288ee324cd30e027462d8eaaffff445a1105b7e4fc1302894' self.assertEqual(exp_result, pyqrllib.bin2hstr(mnemonic2bin(long_mnemonic)))
def recover(seed_type): """ Recover Wallet using hexseed or mnemonic (32 words) """ seed = click.prompt('Please enter your %s' % (seed_type, )) seed = seed.lower().strip() if seed_type == 'mnemonic': words = seed.split() if len(words) != 32: print('You have entered %s words' % (len(words), )) print('Mnemonic seed must contain only 32 words') return bin_seed = mnemonic2bin(seed) else: if len(seed) != 96: print('You have entered hexseed of %s characters' % (len(seed), )) print('Hexseed must be of only 96 characters.') return bin_seed = hstr2bin(seed) walletObj = get_wallet_obj() addrBundle = walletObj.get_new_address(seed=bin_seed) print('Recovered Wallet Address : %s' % (addrBundle.address.decode(), )) for addr in walletObj.address_bundle: if addrBundle.address == addr.address: print('Wallet Address is already in the wallet list') return if click.confirm('Do you want to save the recovered wallet?'): walletObj.address_bundle.append(addrBundle) click.echo('Saving...') walletObj.save_wallet() click.echo('Done')
def _recoverfromwords(self, args): if not args: self.output['message'].write( '>>> Usage: recoverfromwords <paste in 32 mnemonic words>\r\n') return True self.output['message'].write( '>>> trying..this could take up to a minute..\r\n') if len(args) != 32: self.output['message'].write( '>>> Usage: recoverfromwords <paste in 32 mnemonic words>\r\n') return True args = ' '.join(args) addr = self.factory.chain.wallet.get_new_address(address_type='XMSS', seed=mnemonic2bin( args, wordlist)) self.factory.newaddress = addr self.output['status'] = 0 self.output['message'].write('>>> Recovery address: ' + addr[1].get_address() + '\r\n') self.output['message'].write('>>> Recovery hexSEED: ' + addr[1].get_hexseed() + '\r\n') self.output['message'].write('>>> Mnemonic confirm: ' + addr[1].get_mnemonic() + '\r\n') self.output['message'].write( '>>> savenewaddress if Qaddress matches expectations..\r\n') self.output['keys'] += [ 'recovery_address', 'recovery_hexseed', 'mnemonic_confirm' ] self.output['recovery_address'] = addr[1].get_address() self.output['recovery_hexseed'] = addr[1].get_hexseed() self.output['mnemonic_confirm'] = addr[1].get_mnemonic()
def _get_xmss_by_index_no_cache(self, idx) -> Optional[XMSS]: """ Generates an XMSS tree based on the information contained in the wallet :param idx: The index of the address item :return: An XMSS tree object """ if idx >= len(self._address_items): return None item = self._address_items[idx] extended_seed = mnemonic2bin(item.mnemonic.strip()) tmp_xmss = XMSS.from_extended_seed(extended_seed) tmp_xmss.set_ots_index(item.index) if item.qaddress != 'Q' + bin2hstr(tmp_xmss.address): raise Exception("Mnemonic and address do not match.") if item.hexseed != tmp_xmss.hexseed: raise Exception("hexseed does not match.") if item.mnemonic != tmp_xmss.mnemonic: raise Exception("mnemonic does not match.") if item.height != tmp_xmss.height: raise Exception("height does not match.") return tmp_xmss
def generate_slave_from_input(slaves_filename): # FIXME: Refactor and improve error handling extended_seed = '' logger.warning('No Slave Seeds found!!') logger.warning('It is highly recommended to use the slave for mining') try: ans = input('Do you want to use main wallet for mining? (Y/N) ') if ans == 'N': quit(0) extended_seed = input( 'Enter hex or mnemonic seed of mining wallet ').encode() except KeyboardInterrupt: quit(0) bin_extended_seed = None if len(extended_seed) == 102: # hexseed bin_extended_seed = hstr2bin(extended_seed.decode()) elif len(extended_seed.split()) == 34: bin_extended_seed = mnemonic2bin(extended_seed.decode()) if bin_extended_seed is None: logger.warning('Invalid XMSS seed') quit(1) addrBundle = XMSS.from_extended_seed(bin_extended_seed) slaves = [ bin2hstr(addrBundle.xmss.address), [addrBundle.xmss.extended_seed], None ] write_slaves(slaves_filename, slaves)
def get_xmss_by_item(self, item: AddressItem, ots_index=-1) -> XMSS: """ Generates an XMSS tree based on the given AddressItem :param item: :param ots_index: :return: """ extended_seed = mnemonic2bin(item.mnemonic.strip()) tmp_xmss = XMSS.from_extended_seed(extended_seed) if ots_index > -1: tmp_xmss.set_ots_index(ots_index) else: tmp_xmss.set_ots_index(item.index) if item.qaddress != 'Q' + bin2hstr(tmp_xmss.address): raise Exception("Mnemonic and address do not match.") if item.hexseed != tmp_xmss.hexseed: raise Exception("hexseed does not match.") if item.mnemonic != tmp_xmss.mnemonic: raise Exception("mnemonic does not match.") if item.height != tmp_xmss.height: raise Exception("height does not match.") return tmp_xmss
def _read_wallet(self): self.address_bundle = [] if not os.path.isfile(self.wallet_dat_filename): upgraded = self._upgrade_old_wallet() if not upgraded: return try: logger.info('Retrieving wallet file') with open(self.wallet_dat_filename, "rb") as infile: wallet_store = qrl_pb2.WalletStore() wallet_store.ParseFromString(bytes(infile.read())) self.address_bundle = [] for a in wallet_store.wallets: tmpxmss = XMSS(config.dev.xmss_tree_height, mnemonic2bin(a.mnemonic.strip())) tmpxmss.set_index(a.xmss_index) if a.address != tmpxmss.get_address(): logger.fatal("Mnemonic and address do not match.") exit(1) self.address_bundle.append( AddressBundle(tmpxmss.get_address().encode(), tmpxmss)) except Exception as e: logger.warning("It was not possible to open the wallet: %s", e)
def _read_wallet(self): self.address_bundle = None if not os.path.isfile(self.wallet_dat_filename): return try: logger.info('Retrieving wallet file') with open(self.wallet_dat_filename, "r") as infile: data = json.load(infile) self.address_bundle = [] for a in data: tmpxmss = XMSS( config.dev.xmss_tree_height, mnemonic2bin(a['mnemonic'].strip(), wordlist)) tmpxmss.set_index(a['index']) self.address_bundle.append( AddressBundle(tmpxmss.get_address(), tmpxmss)) except Exception as e: logger.warning("It was not possible to open the wallet: %s", e)
def add_address_from_seed(self, seed=None) -> str: self.authenticate() words = seed.split() if len(words) == 34: bin_seed = mnemonic2bin(seed) elif len(seed) == 102: bin_seed = hstr2bin(seed) else: raise ValueError("Invalid Seed") address_from_seed = XMSS.from_extended_seed(bin_seed) if self._wallet.get_xmss_by_qaddress(address_from_seed.qaddress, self._passphrase): raise Exception("Address is already in the wallet") self._wallet.append_xmss(address_from_seed) self._encrypt_last_item() self._wallet.save() return address_from_seed.qaddress
def _upgrade_old_wallet(self): wallet_old_dat_filename = os.path.join(config.user.wallet_path, config.dev.wallet_old_dat_filename) if not os.path.isfile(wallet_old_dat_filename): return False logger.info("Found old wallet format. Upgrading") try: logger.info('Retrieving wallet file') with open(wallet_old_dat_filename, "r") as infile: data = json.load(infile) self.address_bundle = [] for a in data: tmpxmss = XMSS(config.dev.xmss_tree_height, mnemonic2bin(a['mnemonic'].strip())) tmpxmss.set_index(a['index']) self.address_bundle.append(AddressBundle(tmpxmss.get_address().encode(), tmpxmss)) except Exception as e: logger.warning("It was not possible to open the wallet: %s", e) logger.info("Saving in the new format") self.save_wallet()
def wallet_recover(ctx, seed_type): """ Recovers a wallet from a hexseed or mnemonic (32 words) """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return seed = click.prompt('Please enter your %s' % (seed_type, )) seed = seed.lower().strip() if seed_type == 'mnemonic': words = seed.split() if len(words) != 34: print('You have entered %s words' % (len(words), )) print('Mnemonic seed must contain only 34 words') return bin_seed = mnemonic2bin(seed) else: if len(seed) != 102: print('You have entered hexseed of %s characters' % (len(seed), )) print('Hexseed must be of only 102 characters.') return bin_seed = hstr2bin(seed) walletObj = Wallet(wallet_path=ctx.obj.wallet_path) recovered_xmss = XMSS.from_extended_seed(bin_seed) print('Recovered Wallet Address : %s' % (Wallet._get_Qaddress(recovered_xmss.address), )) for addr in walletObj.address_items: if recovered_xmss.qaddress == addr.qaddress: print('Wallet Address is already in the wallet list') return if click.confirm('Do you want to save the recovered wallet?'): click.echo('Saving...') walletObj.append_xmss(recovered_xmss) walletObj.save() click.echo('Done') _print_addresses(ctx, walletObj.address_items, config.user.wallet_dir)
def mining_wallet_checks(args): slaves_filename = os.path.join(config.user.wallet_dir, config.user.slaves_filename) if args.randomizeSlaveXMSS: addrBundle = Wallet.get_new_address() slaves = [bin2hstr(addrBundle.xmss.address), [addrBundle.xmss.extended_seed], None] write_slaves(slaves_filename, slaves) try: slaves = read_slaves(slaves_filename) except FileNotFoundError: logger.warning('No Slave Seeds found!!') logger.warning('It is highly recommended to use the slave for mining') try: ans = input('Do you want to use main wallet for mining? (Y/N) ') if ans == 'N': quit(0) seed = input('Enter hex or mnemonic seed of mining wallet ').encode() except KeyboardInterrupt: quit(0) if len(seed) == 102: # hexseed bin_seed = hstr2bin(seed.decode()) elif len(seed.split()) == 34: bin_seed = mnemonic2bin(seed.decode()) else: logger.warning('Invalid XMSS seed') quit(1) addrBundle = Wallet.get_new_address(signature_tree_height=None, seed=bin_seed) slaves = [bin2hstr(addrBundle.xmss.address), [addrBundle.xmss.extended_seed], None] write_slaves(slaves_filename, slaves) slaves = read_slaves(slaves_filename) except KeyboardInterrupt: quit(1) except Exception as e: logger.error('Exception %s', e) quit(1) return slaves
def wallet_recover(ctx, seed_type): """ Recovers a wallet from a hexseed or mnemonic (32 words) """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return seed = click.prompt('Please enter your %s' % (seed_type, )) seed = seed.lower().strip() if seed_type == 'mnemonic': words = seed.split() if len(words) != 34: print('You have entered %s words' % (len(words), )) print('Mnemonic seed must contain only 34 words') return bin_seed = mnemonic2bin(seed) else: if len(seed) != 102: print('You have entered hexseed of %s characters' % (len(seed), )) print('Hexseed must be of only 102 characters.') return bin_seed = hstr2bin(seed) config.user.wallet_dir = ctx.obj.wallet_dir walletObj = Wallet() addrBundle = walletObj.get_new_address(signature_tree_height=None, seed=bin_seed) print('Recovered Wallet Address : %s' % (addrBundle.address.decode(), )) for addr in walletObj.address_bundle: if addrBundle.address == addr.address: print('Wallet Address is already in the wallet list') return if click.confirm('Do you want to save the recovered wallet?'): walletObj.address_bundle.append(addrBundle) click.echo('Saving...') walletObj.save_wallet() click.echo('Done')
def mining_wallet_checks(args): slaves_filename = os.path.join(config.user.wallet_dir, config.user.slaves_filename) if args.randomizeSlaveXMSS: addrBundle = Wallet.get_new_address() slaves = [addrBundle.xmss.get_address(), [addrBundle.xmss.get_seed()], None] write_slaves(slaves_filename, slaves) try: slaves = read_slaves(slaves_filename) except FileNotFoundError: logger.warning('No Slave Seeds found!!') logger.warning('It is highly recommended to use the slave for mining') try: ans = input('Do you want to use main wallet for mining? (Y/N) ') if ans == 'N': quit(0) seed = input('Enter hex or mnemonic seed of mining wallet ').encode() except KeyboardInterrupt: quit(0) if len(seed) == 96: # hexseed bin_seed = hstr2bin(seed.decode()) elif len(seed.split()) == 32: bin_seed = mnemonic2bin(seed.decode()) else: logger.warning('Invalid XMSS seed') quit(1) addrBundle = Wallet.get_new_address(seed=bin_seed) slaves = [addrBundle.xmss.get_address(), [addrBundle.xmss.get_seed()], None] write_slaves(slaves_filename, slaves) slaves = read_slaves(slaves_filename) except KeyboardInterrupt: quit(1) except Exception as e: logger.error('Exception %s', e) quit(1) return slaves
def wallet_recover(ctx, seed_type): """ Recovers a wallet from a hexseed or mnemonic (32 words) """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return seed = click.prompt('Please enter your %s' % (seed_type,)) seed = seed.lower().strip() if seed_type == 'mnemonic': words = seed.split() if len(words) != 32: print('You have entered %s words' % (len(words),)) print('Mnemonic seed must contain only 32 words') return bin_seed = mnemonic2bin(seed) else: if len(seed) != 96: print('You have entered hexseed of %s characters' % (len(seed),)) print('Hexseed must be of only 96 characters.') return bin_seed = hstr2bin(seed) config.user.wallet_dir = ctx.obj.wallet_dir walletObj = Wallet() addrBundle = walletObj.get_new_address(seed=bin_seed) print('Recovered Wallet Address : %s' % (addrBundle.address.decode(),)) for addr in walletObj.address_bundle: if addrBundle.address == addr.address: print('Wallet Address is already in the wallet list') return if click.confirm('Do you want to save the recovered wallet?'): walletObj.address_bundle.append(addrBundle) click.echo('Saving...') walletObj.save_wallet() click.echo('Done')
def _read_wallet(self): self.address_bundle = [] if not os.path.isfile(self.wallet_dat_filename): return try: with open(self.wallet_dat_filename, "rb") as infile: wallet_store = qrl_pb2.WalletStore() wallet_store.ParseFromString(bytes(infile.read())) self.address_bundle = [] for a in wallet_store.wallets: tmpxmss = XMSS.from_extended_seed(mnemonic2bin(a.mnemonic.strip())) tmpxmss.set_ots_index(a.xmss_index) if a.address != bin2hstr(tmpxmss.address).encode(): logger.fatal("Mnemonic and address do not match.") exit(1) self.address_bundle.append(AddressBundle(a.address, tmpxmss)) except Exception as e: logger.warning("It was not possible to open the wallet: %s", e)
def parse_cmd(self, data): # Get entered line as an array of strings delimited by "space." # Will chomp away any extra spaces data = data.split() # Arguments include anything beyond the first index if len(data) != 0: # if anything was entered command = data[0] args = None if len(data) > 0: # args optional args = data[1:] if command.decode('utf-8') in self.cmd_list: # Use switch cases when porting to a different language if command == b'create': self.factory.p2pFactory.pos.create_next_block(int(args[0])) self.output['status'] = 0 self.output['message'].write('Creating blocknumber #' + str(args[0])) elif command == b'getnewaddress': self.getnewaddress(args) elif command == b'hexseed': for addr_bundle in self.factory.chain.wallet.address_bundle: if isinstance(addr_bundle.xmss, XMSS): self.output['status'] = 0 self.output['message'].write( 'Address: ' + addr_bundle.xmss.get_address() + '\r\n') self.output['message'].write( 'Recovery seed: ' + addr_bundle.xmss.get_hexseed() + '\r\n') self.output['keys'] += ['Address', 'Recovery seed'] self.output[ 'Address'] = addr_bundle.xmss.get_address() self.output[ 'Recovery seed'] = addr_bundle.xmss.get_hexseed( ) elif command == b'seed': for addr_bundle in self.factory.chain.wallet.address_bundle: if isinstance(addr_bundle.xmss, XMSS): self.output['status'] = 0 self.output['message'].write( 'Address: ' + addr_bundle.xmss.get_address() + '\r\n') self.output['message'].write( 'Recovery seed: ' + addr_bundle.xmss.get_mnemonic() + '\r\n') self.output['keys'] += ['Address', 'Recovery seed'] elif command == b'search': if not args: self.output['status'] = 1 self.output['message'].write( '>>> Usage: search <txhash or Q-address>\r\n') return tmp_output = None if args[0][0] == 'Q': tmp_output = json.loads( self.factory.chain.search_address(args[0])) self.output['message'].write('Address: ' + str(args[0])) self.output['message'].write( '\r\nBalance: ' + str(tmp_output['state']['balance'])) self.output['message'].write( '\r\nTransactions: ' + str(tmp_output['state']['transactions'])) for tx in tmp_output['transactions']: self.output['message'].write(str(tx['txhash'])) self.output['message'].write(' ') self.output['message'].write(str(tx['txfrom'])) self.output['message'].write(' ') self.output['message'].write(str(tx['txto'])) self.output['message'].write(' ') self.output['message'].write(str(tx['amount'])) self.output['message'].write('\r\n') else: tmp_output = json.loads( self.factory.chain.search_txhash(args[0])) self.output['message'].write('Txnhash: ') self.output['message'].write(args[0]) if tmp_output['status'] == 'Error': self.output['message'].write('\r\n') self.output['message'].write( str(tmp_output['error'])) self.output['message'].write('\r\n') return True self.output['message'].write('\r\nTimestamp: ') self.output['message'].write(tmp_output['timestamp']) self.output['message'].write('\r\nBlockNumber: ') self.output['message'].write(tmp_output['block']) self.output['message'].write('\r\nConfirmations: ') self.output['message'].write( tmp_output['confirmations']) self.output['message'].write('\r\nAmount: ') self.output['message'].write(tmp_output['amount']) self.output['message'].write('\r\n') if not tmp_output: self.output['status'] = 1 self.output['message'].write( '>>> No Information available') return True for key in list(tmp_output.keys()): self.output['keys'] += [str(key)] self.output[key] = tmp_output[key] self.output['status'] = 0 self.output['message'].write('') elif command == b'json_block': if not args: self.output['message'].write( helper.json_print_telnet( self.factory.chain.m_get_last_block()) + '\r\n') return True try: int(args[0]) except: self.output['message'].write( '>>> Try "json_block <block number>" \r\n') return True if int(args[0]) > self.factory.chain.m_blockheight(): self.output['message'].write( '>>> Block > Blockheight\r\n') return True self.output['status'] = 0 self.output['message'].write( helper.json_print_telnet( self.factory.chain.m_get_block(int(args[0]))) + '\r\n') elif command == b'savenewaddress': self.savenewaddress() elif command == b'recoverfromhexseed': if not args or not hexseed_to_seed(args[0]): self.output['message'].write( '>>> Usage: recoverfromhexseed <paste in hexseed>\r\n' ) self.output['message'].write( '>>> Could take up to a minute..\r\n') self.output['message'].write( '>>> savenewaddress if Qaddress matches expectations..\r\n' ) return True self.output['status'] = 0 addr = self.factory.chain.wallet.get_new_address( address_type='XMSS', seed=hexseed_to_seed(args[0])) self.factory.newaddress = addr self.output['message'].write('>>> Recovery address: ' + addr[1].get_address() + '\r\n') self.output['message'].write('>>> Recovery seed phrase: ' + addr[1].get_mnemonic() + '\r\n') self.output['message'].write('>>> hexSEED confirm: ' + addr[1].get_hexseed() + '\r\n') self.output['message'].write( '>>> savenewaddress if Qaddress matches expectations..\r\n' ) self.output['keys'] += [ 'recovery_address', 'recovery_seed_phrase', 'hexseed_confirm' ] self.output['recovery_address'] = addr[1].get_address() self.output['recovery_seed_phrase'] = addr[1].get_mnemonic( ) self.output['hexseed_confirm'] = addr[1].get_hexseed() elif command == b'recoverfromwords': if not args: self.output['message'].write( '>>> Usage: recoverfromwords <paste in 32 mnemonic words>\r\n' ) return True self.output['message'].write( '>>> trying..this could take up to a minute..\r\n') if len(args) != 32: self.output['message'].write( '>>> Usage: recoverfromwords <paste in 32 mnemonic words>\r\n' ) return True args = ' '.join(args) addr = self.factory.chain.wallet.get_new_address( address_type='XMSS', seed=mnemonic2bin(args, wordlist)) self.factory.newaddress = addr self.output['status'] = 0 self.output['message'].write('>>> Recovery address: ' + addr[1].get_address() + '\r\n') self.output['message'].write('>>> Recovery hexSEED: ' + addr[1].get_hexseed() + '\r\n') self.output['message'].write('>>> Mnemonic confirm: ' + addr[1].get_mnemonic() + '\r\n') self.output['message'].write( '>>> savenewaddress if Qaddress matches expectations..\r\n' ) self.output['keys'] += [ 'recovery_address', 'recovery_hexseed', 'mnemonic_confirm' ] self.output['recovery_address'] = addr[1].get_address() self.output['recovery_hexseed'] = addr[1].get_hexseed() self.output['mnemonic_confirm'] = addr[1].get_mnemonic() elif command == b'stake': self.output['status'] = 0 self.output['message'].write( '>> Toggling stake from: ' + str(self.factory.p2pFactory.stake) + ' to: ' + str(not self.factory.p2pFactory.stake) + '\r\n') self.factory.p2pFactory.stake = not self.factory.p2pFactory.stake logger.info( ('STAKING set to: ', self.factory.p2pFactory.stake)) self.output['keys'] += ['stake'] self.output['stake'] = self.factory.p2pFactory.stake elif command == b'stakenextepoch': self.output['status'] = 0 self.output['message'].write( '>>> Sending a stake transaction for address: ' + self.factory.chain.mining_address + ' to activate next epoch(' + str(config.dev.blocks_per_epoch - (self.factory.chain.m_blockchain[-1].blockheader. blocknumber - (self.factory.chain.m_blockchain[-1].blockheader. epoch * config.dev.blocks_per_epoch))) + ' blocks time)\r\n') logger.info(('STAKE for address:', self.factory.chain.mining_address)) blocknumber = self.factory.chain.block_chain_buffer.height( ) + 1 self.factory.p2pFactory.pos.make_st_tx( blocknumber=blocknumber, first_hash=None) elif command == b'send': self.send_tx(args) elif command == b'mempool': self.output['status'] = 0 self.output['message'].write( '>>> Number of transactions in memory pool: ' + str(len(self.factory.chain.transaction_pool)) + '\r\n') self.output['keys'] += ['txn_nos'] self.output['txn_nos'] = len( self.factory.chain.transaction_pool) elif command == b'help': self.output['status'] = 0 self.output['message'].write( '>>> QRL ledger help: try {}'.format(', '.join( self.cmd_list)) + '\r\n') # removed 'hrs, hrs_check,' elif command == b'quit' or command == b'exit': self.transport.loseConnection() elif command == b'listaddresses': addresses, num_sigs, types = self.factory.chain.wallet.inspect_wallet( ) self.output['status'] = 0 self.output['keys'] += ['addresses'] self.output['addresses'] = [] for addr_bundle in range(len(addresses)): self.output['message'].write( str(addr_bundle) + ', ' + addresses[addr_bundle] + '\r\n') self.output['addresses'] += [addresses[addr_bundle]] elif command == b'wallet': self.wallet() elif command == b'getinfo': self.output['status'] = 0 self.output['message'].write( '>>> Version: ' + self.factory.chain.version_number + '\r\n') self.output['message'].write('>>> Uptime: ' + str(time.time() - self.factory.start_time) + '\r\n') self.output['message'].write( '>>> Nodes connected: ' + str(len(self.factory.p2pFactory.peer_connections)) + '\r\n') self.output['message'].write( '>>> Staking set to: ' + str(self.factory.p2pFactory.stake) + '\r\n') self.output['message'].write( '>>> Sync status: ' + self.factory.p2pFactory.nodeState.state.name + '\r\n') self.output['keys'] += [ 'version', 'uptime', 'nodes_connected', 'staking_status', 'sync_status' ] self.output['version'] = self.factory.chain.version_number self.output['uptime'] = str(time.time() - self.factory.start_time) self.output['nodes_connected'] = str( len(self.factory.p2pFactory.peer_connections)) self.output['staking_status'] = str( self.factory.p2pFactory.stake) self.output[ 'sync_status'] = self.factory.p2pFactory.nodeState.state.name elif command == b'blockheight': self.output['status'] = 0 self.output['message'].write( '>>> Blockheight: ' + str(self.factory.chain.m_blockheight()) + '\r\n') self.output['message'].write( '>>> Headerhash: ' + bin2hstr(self.factory.chain.m_blockchain[-1]. blockheader.headerhash) + '\r\n') self.output['keys'] += ['blockheight', 'headerhash'] self.output[ 'blockheight'] = self.factory.chain.m_blockheight() self.output['headerhash'] = bin2hstr( self.factory.chain.m_blockchain[-1].blockheader. headerhash) elif command == b'peers': self.output['status'] = 0 self.output['message'].write('>>> Connected Peers:\r\n') self.output['keys'] += ['peers'] self.output['peers'] = {} for peer in self.factory.p2pFactory.peer_connections: self.output['message'].write('>>> ' + peer.conn_identity + " [" + peer.version + "] blockheight: " + str(peer.blockheight) + '\r\n') self.output['peers'][peer.conn_identity] = {} self.output['peers'][ peer.conn_identity]['version'] = peer.version self.output['peers'][peer.conn_identity][ 'blockheight'] = peer.blockheight elif command == b'reboot': if len(args) < 1: self.output['message'].write( '>>> reboot <password>\r\n') self.output['message'].write('>>> or\r\n') self.output['message'].write( '>>> reboot <password> <nonce>\r\n') self.output['message'].write('>>> or\r\n') self.output['message'].write( '>>> reboot <password> <nonce> <trim_blocknum>\r\n' ) return True json_hash, err = None, None if len(args) == 3: json_hash, status = self.factory.chain.generate_reboot_hash( args[0], args[1], args[2]) self.output['message'].write( str(args[0]) + str(args[1]) + str(args[2])) elif len(args) == 2: json_hash, status = self.factory.chain.generate_reboot_hash( args[0], args[1]) else: json_hash, status = self.factory.chain.generate_reboot_hash( args[0]) if json_hash: self.factory.p2pFactory.send_reboot(json_hash) # self.factory.state.update(NState.synced) self.output['message'].write(status) else: return False return True
def render_POST(self, request): req = request.content.read() jsQ = json.loads(req) self.result = { 'status': 'fail', 'message': '', 'recoveredAddress': '', 'hexseed': '', 'mnemonic': '' } # Recover address from mnemonic if jsQ["type"] == "mnemonic": # Fail if no words provided if not jsQ["words"]: self.result[ "message"] = "You must provide your mnemonic phrase!" return bytes(helper.json_encode(self.result), 'utf-8') # FIXME: Validation should not be here, it should be part of mnemonic mnemonicphrase = jsQ["words"] if not validate_mnemonic(mnemonicphrase): self.result[ "message"] = "Invalid mnemonic phrase! It must contain exactly 32 valid words" return bytes(helper.json_encode(self.result), 'utf-8') # Try to recover try: addr = self.chain.wallet.get_new_address( seed=mnemonic2bin(mnemonicphrase, wordlist)) self.chain.wallet.append_wallet(addr) # Find hex/mnemonic for recovered wallet self.result["recoveredAddress"] = addr[1].get_address() self.result["hexseed"] = addr[1].get_hexseed() self.result["mnemonic"] = addr[1].get_mnemonic() except: self.result[ "message"] = "There was a problem restoring your address. " \ "If you believe this is in error, please raise it with the QRL team." return bytes(helper.json_encode(self.result), 'utf-8') # Recover address from hexseed elif jsQ["type"] == "hexseed": if not jsQ["hexseed"] or not hexseed_to_seed(jsQ["hexseed"]): self.result["message"] = "Invalid Hex Seed!" return bytes(helper.json_encode(self.result), 'utf-8') # Try to recover try: addr = self.chain.wallet.get_new_address( seed=hexseed_to_seed(jsQ["hexseed"])) self.chain.wallet.append_wallet(addr) # Find hex/mnemonic for recovered wallet self.result["recoveredAddress"] = addr[1].get_address() self.result["hexseed"] = addr[1].get_hexseed() self.result["mnemonic"] = addr[1].get_mnemonic() except: self.result[ "message"] = "There was a problem restoring your address. If you believe this is in error, please raise it with the QRL team." return bytes(helper.json_encode(self.result), 'utf-8') # Invalid selection else: self.result[ "message"] = "You must select either mnemonic or hexseed recovery options to restore an address!" return bytes(helper.json_encode(self.result), 'utf-8') # If we got this far, it must have worked! self.result["status"] = "success" return bytes(helper.json_encode(self.result), 'utf-8')
def test_mnemonic_words_odd_2(self): with self.assertRaises(ValueError): mnemonic2bin('absorb bunny bunny')
def test_mnemonic2(self): result = mnemonic2bin('absorb absorb') self.assertEqual(tuple([1, 0, 16]), result)
def test_mnemonic4(self): bin = mnemonic2bin('absorb absorb') tmp_mnemonic = bin2mnemonic(bin) self.assertEqual('absorb absorb', tmp_mnemonic)