diff --git a/src/codex32/_bitcoin_core.py b/src/codex32/_bitcoin_core.py index 84a73e1..25aaf00 100644 --- a/src/codex32/_bitcoin_core.py +++ b/src/codex32/_bitcoin_core.py @@ -301,11 +301,11 @@ def _select( ask: Callable[[str], str], tell: Callable[[str], None], ) -> str: + def use(name: str) -> bool: + return ask(f"Use blank wallet {json.dumps(name)}? [y/N]").lower() in ("y", "yes") + choices = tuple(name for name in sorted(self._names()) if self._target(name) is not None) - if len(choices) == 1 and ask(f"Use blank wallet {json.dumps(choices[0])}? [y/N]").lower() in ( - "y", - "yes", - ): + if len(choices) == 1 and use(choices[0]): return choices[0] while True: if choices: @@ -316,10 +316,7 @@ def _select( answer = ask("Choose a wallet number") if answer.isdecimal() and 1 <= int(answer) <= len(choices): name = choices[int(answer) - 1] - if ask(f"Use blank wallet {json.dumps(name)}? [y/N]").lower() in ( - "y", - "yes", - ): + if use(name): return name continue if answer != str(len(choices) + 1): @@ -339,10 +336,7 @@ def _select( if appeared: break choices = tuple(name for name in sorted(names) if self._target(name) is not None) - if len(appeared) == 1 and ask(f"Use blank wallet {json.dumps(appeared[0])}? [y/N]").lower() in ( - "y", - "yes", - ): + if len(appeared) == 1 and use(appeared[0]): return appeared[0] def initialize( diff --git a/src/codex32/cli.py b/src/codex32/cli.py index a9ff364..8b27eb8 100644 --- a/src/codex32/cli.py +++ b/src/codex32/cli.py @@ -50,7 +50,7 @@ _residue_low_discrimination, correct_worksheet_residue, ) -from codex32.errors import CodexError, HeaderCollision, InvalidCorrectionInput +from codex32.errors import CodexError, InvalidCorrectionInput from codex32.generation import ( ConfirmationResult, CreationCeremony, @@ -109,12 +109,11 @@ def _secret(artifacts: list[Artifact]) -> Secret: def _master_seed(fingerprint: Callable[[MasterSeed], bytes] | None = None) -> MasterSeed: - if isinstance( - value := _secret(_artifacts(profiles=(Profile.MS,), initial_prefix="MS1", fingerprint=fingerprint)), + # Only ms input is accepted, and an ms secret is always a MasterSeed. + return cast( MasterSeed, - ): - return value - raise _UsageError("Wallet commands accept only Bitcoin master-seed secrets.") + _secret(_artifacts(profiles=(Profile.MS,), initial_prefix="MS1", fingerprint=fingerprint)), + ) def _summary(artifact: Artifact, *, valid: bool = False) -> list[str]: @@ -483,8 +482,6 @@ def _create( ) -> int: profile, selected_threshold, identifier = _creation_header(header) threshold = 0 if selected_threshold is None else selected_threshold - if profile is not Profile.MS: - raise _UsageError("Only Bitcoin master-seed backups can be created.") if shares is not None and indices is not None: raise _UsageError("Choose either --shares or --indices, not both.") if byte_length is not None and existing: @@ -498,8 +495,6 @@ def _create( raise _UsageError("For thresholds 4 through 9, choose --shares or --indices.") core = _connected_core() source = _creation_source(profile) if existing else None - if not existing and not sys.stdin.isatty() and _text("", optional=True): - raise _UsageError("Use --existing when supplying a seed or secret.") if isinstance(source, (Share, Secret)) and not isinstance(source, MasterSeed): raise _UsageError(f"Enter one {_profile_rules(profile).label}, not a share or another backup type.") try: @@ -547,8 +542,6 @@ def _create( share_count=shares, indices=indices, ) - except HeaderCollision as error: - raise _CommandError(f"{error}; choose another set header") from error except CodexError as error: raise _CommandError(str(error)) from error output_count = shares if shares is not None else len(indices or "")