Example #1
1
File: Wallet.py Project: fanff/QRL
    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)
Example #2
0
    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)))
Example #3
0
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')
Example #4
0
    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()
Example #5
0
    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)
Example #7
0
    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
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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
Example #11
0
    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()
Example #12
0
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)
Example #13
0
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
Example #14
0
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')
Example #15
0
File: main.py Project: fanff/QRL
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
Example #16
0
File: cli.py Project: fanff/QRL
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')
Example #17
0
    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)
Example #18
0
    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
Example #19
0
    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')
Example #20
0
 def test_mnemonic_words_odd_2(self):
     with self.assertRaises(ValueError):
         mnemonic2bin('absorb bunny bunny')
Example #21
0
 def test_mnemonic2(self):
     result = mnemonic2bin('absorb absorb')
     self.assertEqual(tuple([1, 0, 16]), result)
Example #22
0
 def test_mnemonic4(self):
     bin = mnemonic2bin('absorb absorb')
     tmp_mnemonic = bin2mnemonic(bin)
     self.assertEqual('absorb absorb', tmp_mnemonic)