input.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/env python3
  2. #
  3. # MMGen Wallet, a terminal-based cryptocurrency wallet
  4. # Copyright (C)2013-2025 The MMGen Project <mmgen@tuta.io>
  5. #
  6. # Project source code repository: https://github.com/mmgen/mmgen-wallet
  7. # Licensed according to the terms of GPL Version 3. See LICENSE for details.
  8. """
  9. test.cmdtest_d.include.input: Shared input routines for the cmdtest.py test suite
  10. """
  11. import time
  12. from ...include.common import getrand
  13. from .common import randbool
  14. def stealth_mnemonic_entry(t, mne, mn, entry_mode, pad_entry=False):
  15. def pad_mnemonic(mn, ss_len):
  16. def get_pad_chars(n):
  17. ret = ''
  18. for _ in range(n):
  19. m = int.from_bytes(getrand(1), 'big') % 32
  20. ret += r'123579!@#$%^&*()_+-=[]{}"?/,.<>|'[m]
  21. return ret
  22. ret = []
  23. for w in mn:
  24. if entry_mode == 'short':
  25. w = w[:ss_len]
  26. if len(w) < ss_len:
  27. npc = 3
  28. w = w[0] + get_pad_chars(npc) + w[1:]
  29. if pad_entry:
  30. w += '%' * (1 + mne.em.pad_max - npc)
  31. else:
  32. w += '\n'
  33. else:
  34. w = get_pad_chars(1) + w[0] + get_pad_chars(1) + w[1:]
  35. elif len(w) > (3, 5)[ss_len==12]:
  36. w = w + '\n'
  37. else:
  38. w = (
  39. get_pad_chars(2 if randbool() and entry_mode != 'short' else 0)
  40. + w[0] + get_pad_chars(2) + w[1:]
  41. + get_pad_chars(9))
  42. w = w[:ss_len+1]
  43. ret.append(w)
  44. return ret
  45. match entry_mode:
  46. case 'fixed':
  47. mn = ['bkr'] + mn[:5] + ['nfb'] + mn[5:]
  48. ssl = mne.uniq_ss_len
  49. def gen_mn():
  50. for w in mn:
  51. if len(w) >= ssl:
  52. yield w[:ssl]
  53. else:
  54. yield w[0] + 'z\b' + '#' * (ssl-len(w)) + w[1:]
  55. mn = list(gen_mn())
  56. case 'full' | 'short':
  57. mn = ['fzr'] + mn[:5] + ['grd', 'grdbxm'] + mn[5:]
  58. mn = pad_mnemonic(mn, mne.em.ss_len)
  59. mn[10] = '@#$%*##' + mn[10]
  60. wnum = 1
  61. p_ok, p_err = mne.word_prompt
  62. for w in mn:
  63. ret = t.expect((p_ok.format(wnum), p_err.format(wnum-1)))
  64. if ret == 0:
  65. wnum += 1
  66. for char in w:
  67. t.send(char)
  68. time.sleep(0.005)
  69. def user_dieroll_entry(t, data):
  70. for s in data:
  71. t.expect(r'Enter die roll #.+: ', s, regex=True)
  72. time.sleep(0.005)