def _select_wallet(ctx, src): try: config.user.wallet_dir = ctx.obj.wallet_dir wallet = Wallet() if not wallet.addresses: click.echo('This command requires a local wallet') return if src.isdigit(): src = int(src) try: # FIXME: This should only return pk and index xmss = wallet.get_xmss_by_index(src) return wallet.addresses[src], xmss except IndexError: click.echo('Wallet index not found', color='yellow') quit(1) elif src.startswith('Q'): for i, addr_item in enumerate(wallet.address_items): if src == addr_item.address: xmss = wallet.get_xmss_by_address(wallet.addresses[i]) return wallet.addresses[i], xmss click.echo('Source address not found in your wallet', color='yellow') quit(1) return bytes(hstr2bin(src)), None except Exception as e: click.echo("Error selecting wallet") quit(1)
def wallet_rm(ctx, wallet_idx, skip_confirmation): """ Removes an address from the wallet using the given address index. Warning! Use with caution. Removing an address from the wallet will result in loss of access to the address and is not reversible unless you have address recovery information. Use the wallet_secret command for obtaining the recovery Mnemonic/Hexseed and the wallet_recover command for restoring an address. """ wallet = Wallet(wallet_path=ctx.obj.wallet_path) address_item = get_item_from_wallet(wallet, wallet_idx) if address_item: if not skip_confirmation: click.echo( 'You are about to remove address [{0}]: {1} from the wallet.'. format(wallet_idx, address_item.qaddress)) click.echo( 'Warning! By continuing, you risk complete loss of access to this address if you do not have a ' 'recovery Mnemonic/Hexseed.') click.confirm('Do you want to continue?', abort=True) wallet.remove(address_item.qaddress) _print_addresses(ctx, wallet.address_items, config.user.wallet_dir)
def wallet_rm(ctx, wallet_idx, skip_confirmation): """ Removes an address from the wallet using the given address index. Warning! Use with caution. Removing an address from the wallet will result in loss of access to the address and is not reversible unless you have address recovery information. Use the wallet_secret command for obtaining the recovery Mnemonic/Hexseed and the wallet_recover command for restoring an address. """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return wallet = Wallet(wallet_path=ctx.obj.wallet_path) if 0 <= wallet_idx < len(wallet.address_items): addr_item = wallet.address_items[wallet_idx] if not skip_confirmation: click.echo( 'You are about to remove address [{0}]: {1} from the wallet.'. format(wallet_idx, addr_item.qaddress)) click.echo( 'Warning! By continuing, you risk complete loss of access to this address if you do not have a recovery Mnemonic/Hexseed.' ) click.confirm('Do you want to continue?', abort=True) wallet.remove(addr_item.qaddress) _print_addresses(ctx, wallet.address_items, config.user.wallet_dir) else: click.echo('Wallet index not found', color='yellow')
def test_create_load(self): with set_qrl_dir("no_data"): wallet = Wallet() wallet.add_new_address(height=4) wallet_b = Wallet() self.assertEqual(1, len(wallet_b.address_items)) self.assertEqual(wallet.address_items[0], wallet_b.address_items[0])
def wallet_add(ctx, height): """ Adds an address or generates a new wallet (working directory) """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return wallet = Wallet(wallet_path=ctx.obj.wallet_path) wallet.add_new_address(height) _print_addresses(ctx, wallet.address_items, config.user.wallet_dir)
def test_getnewaddress(self): with set_wallet_dir("test_wallet"): wallet = Wallet() S1 = hstr2bin( '7bf1e7c1c84be2c820211572d990c0430e09401053ce2af489ee3e4d030c027464d9cac1fff449a2405b7f3fc63018a4' ) address = wallet.get_new_address(seed=S1) self.assertIsNotNone(address.address) self.assertEqual( b'Q56e5d6410a5716e548d89ca27b8f057122af9560ba3cd8aa99879f32758330267811af83', address.address)
def test_create(self): with set_qrl_dir("no_data"): wallet = Wallet() self.assertEqual(0, len(wallet.address_items)) xmss1 = wallet.add_new_address(4) self.assertEqual(1, len(wallet.address_items)) xmss2 = wallet.get_xmss_by_index(0) self.assertEqual(xmss1.address, xmss2.address) self.assertEqual(xmss1.mnemonic, xmss2.mnemonic)
def __init__(self, state): self.pstate = state # FIXME: Is this really a parameter? self.chain_dat_filename = os.path.join(config.user.data_path, config.dev.mnemonic_filename) self.wallet = Wallet() # FIXME: Why chain needs access to the wallet? self.blockchain = [] # FIXME: Everyone is touching this # FIXME: Remove completely and trust the db memcache for this # OBSOLETE ???? self._block_framedata = dict( ) # FIXME: this is used to access file chunks. Delete once we move to DB
def wallet_add(ctx): """ Adds an address or generates a new wallet (working directory) """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return config.user.wallet_path = ctx.obj.wallet_dir wallet = Wallet() wallet.append(wallet.get_new_address()) addresses = [a.address for a in wallet.address_bundle] _print_addresses(ctx, addresses, config.user.wallet_path)
def wallet_add(ctx): """ Adds an address or generates a new wallet (working directory) """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return config.user.wallet_dir = ctx.obj.wallet_dir wallet = Wallet() wallet.append(wallet.get_new_address()) addresses = [a.address for a in wallet.address_bundle] _print_addresses(ctx, addresses, config.user.wallet_dir)
def wallet_secret(ctx, wallet_idx): """ Provides the mnemonic/hexseed of the given address index """ wallet = Wallet(wallet_path=ctx.obj.wallet_path) if wallet.encrypted: secret = click.prompt('The wallet is encrypted. Enter password', hide_input=True) wallet.decrypt(secret) address_item = get_item_from_wallet(wallet, wallet_idx) if address_item: click.echo('Wallet Address : {}'.format(address_item.qaddress)) click.echo('Mnemonic : {}'.format(address_item.mnemonic)) click.echo('Hexseed : {}'.format(address_item.hexseed))
def _select_wallet(ctx, src): try: config.user.wallet_dir = ctx.obj.wallet_dir wallet = Wallet() if not wallet.addresses: click.echo('This command requires a local wallet') return if src.isdigit(): try: # FIXME: This should only return pk and index ab = wallet.address_bundle[int(src)] return bytes(hstr2bin(ab.address.decode())), ab.xmss except IndexError: click.echo('Wallet index not found', color='yellow') quit(1) elif src.startswith('Q'): for i, addr in enumerate(wallet.addresses): if src.encode() == addr: return bytes(hstr2bin(wallet.address_bundle[i].address.decode())), wallet.address_bundle[i].xmss click.echo('Source address not found in your wallet', color='yellow') quit(1) return bytes(hstr2bin(src)), None except Exception as e: click.echo("Error selecting wallet") quit(1)
def get_mining_xmss(self): if self._mining_xmss: addr_state = self.state.get_address(self._mining_xmss.address) if self.set_unused_ots_key(self._mining_xmss, addr_state, self._mining_xmss.ots_index): if self.valid_mining_permission(): return self._mining_xmss else: self._mining_xmss = None return None if not self._mining_xmss: self._master_address = self._slaves[0] unused_ots_found = False for slave_seed in self._slaves[1]: xmss = Wallet.get_new_address(signature_tree_height=None, seed=slave_seed).xmss addr_state = self.state.get_address(xmss.address) if self.set_unused_ots_key(xmss, addr_state): # Unused ots_key_found self._mining_xmss = xmss unused_ots_found = True break if not unused_ots_found: # Unused ots_key_found logger.warning('No OTS-KEY left for mining') return None if self._master_address == self._mining_xmss.address: return self._mining_xmss if not self.valid_mining_permission(): return None return self._mining_xmss
def get_mining_xmss(self): if self._mining_xmss: addr_state = self.state.get_address(self._mining_xmss.get_address()) if self.set_unused_ots_key(self._mining_xmss, addr_state, self._mining_xmss.get_index()): if self.valid_mining_permission(): return self._mining_xmss else: self._mining_xmss = None return None if not self._mining_xmss: self._master_address = self._slaves[0].encode() unused_ots_found = False for slave_seed in self._slaves[1]: xmss = Wallet.get_new_address(seed=slave_seed).xmss addr_state = self.state.get_address(xmss.get_address()) if self.set_unused_ots_key(xmss, addr_state): # Unused ots_key_found self._mining_xmss = xmss unused_ots_found = True break if not unused_ots_found: # Unused ots_key_found logger.warning('No OTS-KEY left for mining') return None if self._master_address == self._mining_xmss.get_address(): return self._mining_xmss if not self.valid_mining_permission(): return None return self._mining_xmss
def wallet_ls(ctx): """ Lists available wallets """ config.user.wallet_dir = ctx.obj.wallet_dir wallet = Wallet() _print_addresses(ctx, wallet.address_items, config.user.wallet_dir)
def _select_wallet(ctx, src): try: config.user.wallet_path = ctx.obj.wallet_dir wallet = Wallet(valid_or_create=False) addresses = [a.address for a in wallet.address_bundle] if not addresses: click.echo('This command requires a local wallet') return if src.isdigit(): try: # FIXME: This should only return pk and index ab = wallet.address_bundle[int(src)] return ab.address, ab.xmss except IndexError: click.echo('Wallet index not found', color='yellow') quit(1) elif src.startswith('Q'): for i, addr in enumerate(wallet.addresses): if src.encode() == addr: return wallet.address_bundle[ i].address, wallet.address_bundle[i].xmss click.echo('Source address not found in your wallet', color='yellow') quit(1) return src.encode(), None except Exception as e: click.echo("Error selecting wallet") quit(1)
def test_create_wallet(self): with set_wallet_dir("no_wallet"): wallet = Wallet() self.assertIsNotNone(wallet) wallet_file_path = os.path.join(config.user.wallet_path, "wallet.qrl") self.assertTrue(isfile(wallet_file_path))
def wallet_gen(ctx, height): """ Generates a new wallet with one address """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return # FIXME: If the wallet is there, it should fail wallet = Wallet(wallet_path=ctx.obj.wallet_path) if len(wallet.address_items) == 0: wallet.add_new_address(height) _print_addresses(ctx, wallet.address_items, config.user.wallet_dir) else: # FIXME: !!!!! click.echo("Wallet already exists")
def wallet_ls(ctx): """ Lists available wallets """ wallet = Wallet(wallet_path=ctx.obj.wallet_path) _print_addresses(ctx, wallet.address_items, ctx.obj.wallet_dir)
def wallet_ls(ctx): """ Lists available wallets """ config.user.wallet_dir = ctx.obj.wallet_dir wallet = Wallet(valid_or_create=False) addresses = [a.address for a in wallet.address_bundle] _print_addresses(ctx, addresses, config.user.wallet_dir)
def test_read_ver0(self): with set_qrl_dir("wallet_ver0"): wallet = Wallet() self.assertEqual(1, len(wallet.address_items)) self.assertEqual(wallet.version, 0) addr_item = wallet.address_items[0] self.assertFalse(addr_item.encrypted) self.assertEqual('Q010400d9f1efe5b272e042dcc8ef690f0e90ca8b0b6edba0d26f81e7aff12a6754b21788169f7f', addr_item.qaddress) xmss0 = wallet.get_xmss_by_index(0) self.assertEqual('010400d9f1efe5b272e042dcc8ef690f0e90ca8b0b6edba0d26f81e7aff12a6754b21788169f7f', bin2hstr(xmss0.address)) xmss0b = wallet.get_xmss_by_address(xmss0.address) self.assertEqual('010400d9f1efe5b272e042dcc8ef690f0e90ca8b0b6edba0d26f81e7aff12a6754b21788169f7f', bin2hstr(xmss0b.address))
def wallet_add(ctx, height, hash_function): """ Adds an address or generates a new wallet (working directory) """ secret = None wallet = Wallet(wallet_path=ctx.obj.wallet_path) wallet_was_encrypted = wallet.encrypted if wallet.encrypted: secret = click.prompt('The wallet is encrypted. Enter password', hide_input=True) wallet.decrypt(secret) wallet.add_new_address(height, hash_function) _print_addresses(ctx, wallet.address_items, config.user.wallet_dir) if wallet_was_encrypted: wallet.encrypt(secret) wallet.save()
def wallet_ls(ctx): """ Lists available wallets """ if ctx.obj.remote: addresses = _admin_get_local_addresses(ctx) _print_addresses(ctx, addresses, ctx.obj.node_public_address) else: config.user.wallet_path = ctx.obj.wallet_dir wallet = Wallet(valid_or_create=False) addresses = [a.address for a in wallet.address_bundle] _print_addresses(ctx, addresses, config.user.wallet_path)
def wallet_secret(ctx, wallet_idx): """ Provides the mnemonic/hexseed of the given address index """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return wallet = Wallet(wallet_path=ctx.obj.wallet_path) if wallet.encrypted: secret = click.prompt('The wallet is encrypted. Enter password', hide_input=True) wallet.decrypt(secret) if 0 <= wallet_idx < len(wallet.address_items): address_item = wallet.address_items[wallet_idx] click.echo('Wallet Address : %s' % (address_item.qaddress)) click.echo('Mnemonic : %s' % (address_item.mnemonic)) click.echo('Hexseed : %s' % (address_item.hexseed)) else: click.echo('Wallet index not found', color='yellow')
def wallet_encrypt(ctx): wallet = Wallet(wallet_path=ctx.obj.wallet_path) click.echo('Encrypting wallet at {}'.format(wallet.wallet_path)) secret = click.prompt('Enter password', hide_input=True, confirmation_prompt=True) wallet.encrypt(secret) wallet.save()
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 _select_wallet(ctx, address_or_index): try: wallet = Wallet(wallet_path=ctx.obj.wallet_path) if not wallet.addresses: click.echo('This command requires a local wallet') return if wallet.encrypted: secret = click.prompt('The wallet is encrypted. Enter password', hide_input=True) wallet.decrypt(secret) if address_or_index.isdigit(): address_or_index = int(address_or_index) addr_item = get_item_from_wallet(wallet, address_or_index) if addr_item: # FIXME: This should only return pk and index xmss = wallet.get_xmss_by_index(address_or_index) return wallet.addresses[address_or_index], xmss elif address_or_index.startswith('Q'): for i, addr_item in enumerate(wallet.address_items): if address_or_index == addr_item.qaddress: xmss = wallet.get_xmss_by_address(wallet.addresses[i]) return wallet.addresses[i], xmss click.echo('Source address not found in your wallet', color='yellow') quit(1) return parse_qaddress(address_or_index), None except Exception as e: click.echo("Error selecting wallet") click.echo(str(e)) quit(1)
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 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() 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.address == addr.address: 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) click.echo('Done') _print_addresses(ctx, walletObj.address_items, config.user.wallet_dir)
def test_decrypt_wallet(self): with set_qrl_dir("no_data"): wallet = Wallet() wallet.add_new_address(height=4) wallet.add_new_address(height=4) addresses = wallet.addresses TEST_KEY = 'mytestkey' wallet.encrypt(TEST_KEY) self.assertTrue(wallet.encrypted) wallet.decrypt(TEST_KEY) self.assertEqual(addresses, wallet.addresses) self.assertFalse(wallet.encrypted_partially)
def wallet_gen(ctx): """ Generates a new wallet with one address """ if ctx.obj.remote: click.echo('This command is unsupported for remote wallets') return config.user.wallet_path = ctx.obj.wallet_dir wallet = Wallet() addresses = [a.address for a in wallet.address_bundle] _print_addresses(ctx, addresses, config.user.wallet_path)
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 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 test_read_wallet_ver0_saves_wallet_ver1(self): with set_qrl_dir("wallet_ver0"): wallet = Wallet() self.assertEqual(wallet.version, 0) wallet.version = 1 wallet.save() wallet_reloaded = Wallet() self.assertEqual(wallet_reloaded.version, 1)