Add interactive seed word prompt

This commit is contained in:
thePR0M3TH3AN
2025-07-16 03:40:24 -04:00
parent 9369bac70f
commit 04dc4e05da
3 changed files with 98 additions and 1 deletions

View File

@@ -71,3 +71,71 @@ def masked_input(prompt: str) -> str:
if sys.platform == "win32":
return _masked_input_windows(prompt)
return _masked_input_posix(prompt)
def prompt_seed_words(count: int = 12) -> str:
"""Prompt the user for a BIP-39 seed phrase.
The user is asked for each word one at a time. A numbered list is
displayed showing ``*`` for entered words and ``_`` for words yet to be
provided. After all words are entered the user is asked to confirm each
word individually. If the user answers ``no`` to a confirmation prompt the
word can be re-entered.
Parameters
----------
count:
Number of words to prompt for. Defaults to ``12``.
Returns
-------
str
The complete seed phrase.
Raises
------
ValueError
If the resulting phrase fails ``Mnemonic.check`` validation.
"""
from mnemonic import Mnemonic
m = Mnemonic("english")
words: list[str] = [""] * count
idx = 0
while idx < count:
progress = [f"{i+1}: {'*' if w else '_'}" for i, w in enumerate(words)]
print("\n".join(progress))
entered = input(f"Enter word number {idx+1}: ").strip().lower()
if entered not in m.wordlist:
print("Invalid word, try again.")
continue
words[idx] = entered
idx += 1
for i in range(count):
while True:
response = (
input(f"Is this the correct word for number {i+1}? {words[i]} (Y/N): ")
.strip()
.lower()
)
if response in ("y", "yes"):
break
if response in ("n", "no"):
while True:
new_word = input(f"Re-enter word number {i+1}: ").strip().lower()
if new_word in m.wordlist:
words[i] = new_word
break
print("Invalid word, try again.")
# Ask for confirmation again with the new word
else:
print("Please respond with 'Y' or 'N'.")
continue
phrase = " ".join(words)
if not m.check(phrase):
raise ValueError("Invalid BIP-39 seed phrase")
return phrase