Skip to content

Commit

Permalink
fix: lookup first before parsing raw key
Browse files Browse the repository at this point in the history
  • Loading branch information
willemneal authored and gitbutler-client committed Nov 12, 2024
1 parent d5dcf88 commit 5749322
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 24 deletions.
2 changes: 1 addition & 1 deletion cmd/soroban-cli/src/config/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl Address {
Address::MuxedAccount(muxed_account) => Ok(muxed_account.clone()),
Address::AliasOrSecret(alias) => alias
.parse()
.or_else(|_| Ok(locator.read_identity(alias)?.public_key(hd_path)?)),
.or_else(|_| Ok(locator.get_public_key(alias, hd_path)?)),
}
}

Expand Down
24 changes: 13 additions & 11 deletions cmd/soroban-cli/src/config/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ pub enum Error {
Secret(#[from] secret::Error),
#[error(transparent)]
StrKey(#[from] stellar_strkey::DecodeError),
#[error("failed to parse key {0}")]
Parse(String),
}

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum Key {
Secret(Secret),
PublicKey { public_key: PublicKey },
PublicKey { public_key: Public },
MuxedAccount { muxed_account: MuxedAccount },
}

Expand All @@ -28,7 +30,7 @@ impl Key {
let bytes = match self {
Key::Secret(secret) => secret.public_key(hd_path)?.0,
Key::PublicKey {
public_key: PublicKey(key),
public_key: Public(key),
} => key.0,
Key::MuxedAccount {
muxed_account: MuxedAccount(stellar_strkey::ed25519::MuxedAccount { ed25519, id }),
Expand Down Expand Up @@ -66,14 +68,14 @@ impl FromStr for Key {
if let Ok(muxed_account) = s.parse() {
return Ok(Key::MuxedAccount { muxed_account });
}
todo!("Error handling for invalid key format");
Err(Error::Parse(s.to_owned()))
}
}

impl From<stellar_strkey::ed25519::PublicKey> for Key {
fn from(value: stellar_strkey::ed25519::PublicKey) -> Self {
Key::PublicKey {
public_key: PublicKey(value),
public_key: Public(value),
}
}
}
Expand All @@ -85,24 +87,24 @@ impl From<&stellar_strkey::ed25519::PublicKey> for Key {
}

#[derive(Debug, PartialEq, Eq, serde_with::SerializeDisplay, serde_with::DeserializeFromStr)]
pub struct PublicKey(pub stellar_strkey::ed25519::PublicKey);
pub struct Public(pub stellar_strkey::ed25519::PublicKey);

impl FromStr for PublicKey {
impl FromStr for Public {
type Err = stellar_strkey::DecodeError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(PublicKey(stellar_strkey::ed25519::PublicKey::from_str(s)?))
Ok(Public(stellar_strkey::ed25519::PublicKey::from_str(s)?))
}
}

impl Display for PublicKey {
impl Display for Public {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

impl From<&PublicKey> for stellar_strkey::ed25519::MuxedAccount {
fn from(PublicKey(stellar_strkey::ed25519::PublicKey(key)): &PublicKey) -> Self {
impl From<&Public> for stellar_strkey::ed25519::MuxedAccount {
fn from(Public(stellar_strkey::ed25519::PublicKey(key)): &Public) -> Self {
stellar_strkey::ed25519::MuxedAccount {
id: 0,
ed25519: *key,
Expand Down Expand Up @@ -136,7 +138,7 @@ mod test {
#[test]
fn public_key() {
let key = Key::PublicKey {
public_key: PublicKey(stellar_strkey::ed25519::PublicKey([0; 32])),
public_key: Public(stellar_strkey::ed25519::PublicKey([0; 32])),
};
let serialized = toml::to_string(&key).unwrap();
println!("{serialized}");
Expand Down
38 changes: 26 additions & 12 deletions cmd/soroban-cli/src/config/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ use std::{
};
use stellar_strkey::{Contract, DecodeError};

use crate::{commands::HEADING_GLOBAL, utils::find_config_dir, Pwd};
use crate::{commands::HEADING_GLOBAL, utils::find_config_dir, xdr, Pwd};

use super::{
alias,
key::Key,
key::{self, Key},
network::{self, Network},
secret::Secret,
Config,
Expand Down Expand Up @@ -81,6 +81,10 @@ pub enum Error {
UpgradeCheckReadFailed { path: PathBuf, error: io::Error },
#[error("Failed to write upgrade check file: {path}: {error}")]
UpgradeCheckWriteFailed { path: PathBuf, error: io::Error },
#[error("Only private keys and seed phrases are supported for getting private keys {0}")]
SecretKeyOnly(String),
#[error(transparent)]
Key(#[from] key::Error),
}

#[derive(Debug, clap::Args, Default, Clone)]
Expand Down Expand Up @@ -239,22 +243,32 @@ impl Args {
}

pub fn read_identity(&self, name: &str) -> Result<Key, Error> {
Ok(KeyType::Identity.read_with_global(name, &self.local_config()?)?)
KeyType::Identity.read_with_global(name, &self.local_config()?)
}

pub fn get_private_key(&self, key_or_name: &str) -> Result<Secret, Error> {
if let Ok(signer) = key_or_name.parse::<Secret>() {
Ok(signer)
pub fn read_key(&self, key_or_name: &str) -> Result<Key, Error> {
if let Ok(key) = self.read_identity(key_or_name) {
Ok(key)
} else {
match self.read_identity(key_or_name)? {
Key::Secret(s) => Ok(s),
_ => Err(Error::SecretFileRead {
path: self.alias_path(key_or_name)?,
}),
}
Ok(key_or_name.parse()?)
}
}

pub fn get_private_key(&self, key_or_name: &str) -> Result<Secret, Error> {
match self.read_key(key_or_name)? {
Key::Secret(s) => Ok(s),
_ => Err(Error::SecretKeyOnly(key_or_name.to_string())),
}
}

pub fn get_public_key(
&self,
key_or_name: &str,
hd_path: Option<usize>,
) -> Result<xdr::MuxedAccount, Error> {
Ok(self.read_key(key_or_name)?.public_key(hd_path)?)
}

pub fn read_network(&self, name: &str) -> Result<Network, Error> {
let res = KeyType::Network.read_with_global(name, &self.local_config()?);
if let Err(Error::ConfigMissing(_, _)) = &res {
Expand Down

0 comments on commit 5749322

Please sign in to comment.