Skip to content

--hd-path is silently ignored for plain seed phrase storage in keys generate #2538

@fnando

Description

@fnando

Summary

When storing a key as a plain seed phrase (i.e. no --secure-store and no --as-secret), the --hd-path flag is accepted by stellar keys generate but silently dropped. The stored Secret::SeedPhrase has no hd_path field, so subsequent commands fall back to index 0 (or whatever the default is) unless the user re-passes --hd-path at every call site.

Once #2536 lands and stellar keys add gains a --hd-path flag, the same gap will exist there for the plain seed-phrase path. Whatever fix lands here should apply to both commands.

Context

Spotted while scoping #2536. In cmd/soroban-cli/src/commands/keys/generate.rs:116-132, self.hd_path is only read in the --secure-store and --as-secret branches:

fn secret(&self, print: &Print) -> Result<Secret, Error> {
    let seed_phrase = self.seed_phrase()?;
    if self.secure_store {
        Ok(secure_store::save_secret(print, &self.name, &seed_phrase, self.hd_path, self.overwrite)?)
    } else if self.as_secret {
        let secret: Secret = seed_phrase.into();
        Ok(secret.private_key(self.hd_path)?.into())
    } else {
        Ok(seed_phrase.into()) // <- hd_path dropped
    }
}

Secret::SeedPhrase (in cmd/soroban-cli/src/config/secret.rs) currently carries only { seed_phrase: String } — no path field.

Possible approaches

  1. Warn when --hd-path is provided but won't be honored by the chosen storage mode. Cheapest; no schema change.
  2. Implicitly derive — treat --hd-path without --secure-store as an implicit --as-secret, so a SecretKey at the requested index is stored. Surprising if undocumented.
  3. Persist hd_path on Secret::SeedPhrase — add an optional hd_path field so the path travels with the identity and is applied automatically on later derivations. Requires a schema bump (with #[serde(default)] for backwards compatibility).

Acceptance

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions