label.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/env python3
  2. #
  3. # MMGen Wallet, a terminal-based cryptocurrency wallet
  4. # Copyright (C)2013-2024 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen-wallet
  9. # https://gitlab.com/mmgen/mmgen-wallet
  10. """
  11. xmrwallet.ops.label: Monero wallet ops for the MMGen Suite
  12. """
  13. from ...color import red, pink, cyan, gray
  14. from ...util import msg, ymsg, gmsg, die, make_timestr
  15. from ...ui import keypress_confirm
  16. from ...addr import CoinAddr
  17. from ..rpc import MoneroWalletRPC
  18. from .spec import OpMixinSpec
  19. from .wallet import OpWallet
  20. class OpLabel(OpMixinSpec, OpWallet):
  21. spec_id = 'label_spec'
  22. spec_key = ((1, 'source'),)
  23. opts = ()
  24. wallet_offline = True
  25. async def main(self):
  26. gmsg('\n{a} label for wallet {b}, account #{c}, address #{d}'.format(
  27. a = 'Setting' if self.label else 'Removing',
  28. b = self.source.idx,
  29. c = self.account,
  30. d = self.address_idx
  31. ))
  32. h = MoneroWalletRPC(self, self.source)
  33. h.open_wallet('source')
  34. wallet_data = h.get_wallet_data()
  35. max_acct = len(wallet_data.accts_data['subaddress_accounts']) - 1
  36. if self.account > max_acct:
  37. die(2, f'{self.account}: requested account index out of bounds (>{max_acct})')
  38. ret = h.print_acct_addrs(wallet_data, self.account)
  39. if self.address_idx > len(ret) - 1:
  40. die(2, '{}: requested address index out of bounds (>{})'.format(
  41. self.address_idx,
  42. len(ret) - 1))
  43. addr = ret[self.address_idx]
  44. new_label = f'{self.label} [{make_timestr()}]' if self.label else ''
  45. ca = CoinAddr(self.proto, addr['address'])
  46. from . import addr_width
  47. msg('\n {a} {b}\n {c} {d}\n {e} {f}'.format(
  48. a = 'Address: ',
  49. b = ca.hl(0) if self.cfg.full_address else ca.fmt(0, color=True, width=addr_width),
  50. c = 'Existing label:',
  51. d = pink(addr['label']) if addr['label'] else gray('[none]'),
  52. e = 'New label: ',
  53. f = pink(new_label) if new_label else gray('[none]')))
  54. op = 'remove' if not new_label else 'update' if addr['label'] else 'set'
  55. if addr['label'] == new_label:
  56. ymsg('\nLabel is unchanged, operation cancelled')
  57. elif keypress_confirm(self.cfg, f' {op.capitalize()} label?'):
  58. h.set_label(self.account, self.address_idx, new_label)
  59. ret = h.print_acct_addrs(h.get_wallet_data(print=False), self.account)
  60. label_chk = ret[self.address_idx]['label']
  61. if label_chk != new_label:
  62. ymsg(f'Warning: new label {label_chk!r} does not match requested value!')
  63. return False
  64. else:
  65. msg(cyan('\nLabel successfully {}'.format('set' if op == 'set' else op+'d')))
  66. else:
  67. ymsg('\nOperation cancelled by user request')