diff --git a/Cargo.lock b/Cargo.lock index 7ea00c33f6..ae40ecfee6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5421,7 +5421,7 @@ dependencies = [ "stellar-asset-spec", "stellar-ledger", "stellar-rpc-client", - "stellar-strkey 0.0.16", + "stellar-strkey 0.0.18", "stellar-xdr", "strsim", "strum 0.17.1", @@ -5634,7 +5634,7 @@ dependencies = [ "serde", "serde_json", "soroban-spec", - "stellar-strkey 0.0.16", + "stellar-strkey 0.0.18", "stellar-xdr", "thiserror 1.0.69", "tokio", @@ -5689,7 +5689,7 @@ dependencies = [ "soroban-spec-tools", "stellar-ledger", "stellar-rpc-client", - "stellar-strkey 0.0.16", + "stellar-strkey 0.0.18", "test-case", "testcontainers", "thiserror 1.0.69", @@ -5809,7 +5809,7 @@ dependencies = [ "serde_json", "serial_test", "sha2 0.10.9", - "stellar-strkey 0.0.16", + "stellar-strkey 0.0.18", "stellar-xdr", "test-case", "testcontainers", @@ -5859,14 +5859,9 @@ version = "0.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "084afcb0d458c3d5d5baa2d294b18f881e62cc258ef539d8fdf68be7dbe45520" dependencies = [ - "clap", "crate-git-revision 0.0.6", "data-encoding", "heapless 0.8.0", - "serde", - "serde_json", - "serde_with", - "thiserror 1.0.69", ] [[package]] @@ -5875,9 +5870,14 @@ version = "0.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f34ff61c0ca6f1c2b4169e8d1633417bd9225f58b6175e4e317204565d16277" dependencies = [ + "clap", "crate-git-revision 0.0.9", "data-encoding", "heapless 0.9.3", + "serde", + "serde_json", + "serde_with", + "thiserror 1.0.69", "zeroize", ] diff --git a/Cargo.toml b/Cargo.toml index 023d794096..cf224f29f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ version = "28.0.0-rc.1" # Dependencies from elsewhere shared by crates: [workspace.dependencies] -stellar-strkey = "0.0.16" +stellar-strkey = "0.0.18" sep5 = "0.1.0" base64 = "0.21.2" thiserror = "1.0.46" diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 993cbda7da..d027bc10f5 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -4861,7 +4861,7 @@ Print version information Decode and encode strkey -**Usage:** `stellar strkey ` +**Usage:** `stellar strkey [OPTIONS] ` ###### **Subcommands:** @@ -4870,25 +4870,25 @@ Decode and encode strkey - `zero` — Generate the zero strkey - `version` — Print version information +###### **Options:** + +- `-q`, `--quiet` — Suppress stderr log and warning output + ## `stellar strkey decode` Decode strkey -**Usage:** `stellar strkey decode ` +Reads the strkey from stdin. -###### **Arguments:** - -- `` — Strkey to decode +**Usage:** `stellar strkey decode` ## `stellar strkey encode` Encode strkey -**Usage:** `stellar strkey encode ` - -###### **Arguments:** +Reads the JSON from stdin. -- `` — JSON for Strkey to encode +**Usage:** `stellar strkey encode` ## `stellar strkey zero` diff --git a/cmd/crates/soroban-spec-tools/src/utils.rs b/cmd/crates/soroban-spec-tools/src/utils.rs index f030cc0f88..f9270e7f50 100644 --- a/cmd/crates/soroban-spec-tools/src/utils.rs +++ b/cmd/crates/soroban-spec-tools/src/utils.rs @@ -19,12 +19,43 @@ pub fn padded_hex_from_str(s: &str, n: usize) -> Result, FromHexError> { pub fn contract_id_from_str(contract_id: &str) -> Result<[u8; 32], stellar_strkey::DecodeError> { stellar_strkey::Contract::from_string(contract_id) .map(|strkey| strkey.0) - .or_else(|_| { + .or_else(|e| { // strkey failed, try to parse it as a hex string, for backwards compatibility. + // If that also fails, report the strkey error, since strkey is the expected format. padded_hex_from_str(contract_id, 32) - .map_err(|_| stellar_strkey::DecodeError::Invalid)? - .try_into() - .map_err(|_| stellar_strkey::DecodeError::Invalid) + .ok() + .and_then(|bytes| bytes.try_into().ok()) + .ok_or(e) }) - .map_err(|_| stellar_strkey::DecodeError::Invalid) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn contract_id_from_str_strkey() { + let id = stellar_strkey::Contract([1; 32]); + assert_eq!(contract_id_from_str(&id.to_string()), Ok([1; 32])); + } + + #[test] + fn contract_id_from_str_hex() { + assert_eq!(contract_id_from_str(&"01".repeat(32)), Ok([1; 32])); + let mut expected = [0; 32]; + expected[31] = 1; + assert_eq!(contract_id_from_str("1"), Ok(expected)); + } + + #[test] + fn contract_id_from_str_returns_strkey_error() { + // Change a character in the payload so that the checksum no longer matches. + let id = stellar_strkey::Contract([1; 32]).to_string(); + let id = format!("{}B{}", &id[..10], &id[11..]); + assert_ne!(id, stellar_strkey::Contract([1; 32]).to_string().as_str()); + assert_eq!( + contract_id_from_str(&id), + Err(stellar_strkey::DecodeError::ChecksumMismatch) + ); + } } diff --git a/cmd/crates/soroban-test/src/lib.rs b/cmd/crates/soroban-test/src/lib.rs index 3ce95bb150..24cf73eb44 100644 --- a/cmd/crates/soroban-test/src/lib.rs +++ b/cmd/crates/soroban-test/src/lib.rs @@ -297,6 +297,7 @@ impl TestEnv { self.cmd::(&format!("--hd-path={hd_path}")) .private_key() .unwrap() + .as_unredacted() ) } diff --git a/cmd/crates/soroban-test/tests/it/strkey.rs b/cmd/crates/soroban-test/tests/it/strkey.rs index 77e5948483..785fe803c4 100644 --- a/cmd/crates/soroban-test/tests/it/strkey.rs +++ b/cmd/crates/soroban-test/tests/it/strkey.rs @@ -5,10 +5,8 @@ fn decode() { let sandbox = TestEnv::default(); sandbox .new_assert_cmd("strkey") - .args([ - "decode", - "GAZTAML6YJA5PGKDXONKPSHKL6FYT6OG5I2R7YB7R3B5CETRG7KIJONK", - ]) + .args(["decode"]) + .write_stdin("GAZTAML6YJA5PGKDXONKPSHKL6FYT6OG5I2R7YB7R3B5CETRG7KIJONK") .assert() .success() .stdout( @@ -24,7 +22,8 @@ fn encode() { let sandbox = TestEnv::default(); sandbox .new_assert_cmd("strkey") - .args(["encode", r#"{"public_key_ed25519":"3330317ec241d79943bb9aa7c8ea5f8b89f9c6ea351fe03f8ec3d1127137d484"}"#]) + .args(["encode"]) + .write_stdin(r#"{"public_key_ed25519":"3330317ec241d79943bb9aa7c8ea5f8b89f9c6ea351fe03f8ec3d1127137d484"}"#) .assert() .success() .stdout("GAZTAML6YJA5PGKDXONKPSHKL6FYT6OG5I2R7YB7R3B5CETRG7KIJONK\n"); diff --git a/cmd/soroban-cli/src/commands/keys/secret.rs b/cmd/soroban-cli/src/commands/keys/secret.rs index 9fc00279c2..b2a97395fd 100644 --- a/cmd/soroban-cli/src/commands/keys/secret.rs +++ b/cmd/soroban-cli/src/commands/keys/secret.rs @@ -40,7 +40,7 @@ impl Cmd { if self.phrase { println!("{}", self.seed_phrase()?); } else { - println!("{}", self.private_key()?); + println!("{}", self.private_key()?.as_unredacted()); } Ok(()) diff --git a/cmd/soroban-cli/src/commands/network/root_account/secret.rs b/cmd/soroban-cli/src/commands/network/root_account/secret.rs index a99ab8d45c..36cb7800da 100644 --- a/cmd/soroban-cli/src/commands/network/root_account/secret.rs +++ b/cmd/soroban-cli/src/commands/network/root_account/secret.rs @@ -13,7 +13,7 @@ impl Cmd { pub fn run(&self) -> Result<(), Error> { let root_key = self.args.root_key()?; let private_key = PrivateKey::from_payload(&root_key)?; - println!("{private_key}"); + println!("{}", private_key.as_unredacted()); Ok(()) } } diff --git a/cmd/soroban-cli/src/config/key.rs b/cmd/soroban-cli/src/config/key.rs index 6180e2ed5f..5f281f3ed5 100644 --- a/cmd/soroban-cli/src/config/key.rs +++ b/cmd/soroban-cli/src/config/key.rs @@ -177,7 +177,10 @@ mod test { } #[test] fn secret_key() { - let secret_key = format!("{}", stellar_strkey::ed25519::PrivateKey([0; 32])); + let secret_key = format!( + "{}", + stellar_strkey::ed25519::PrivateKey([0; 32]).as_unredacted() + ); let secret = Secret::SecretKey { secret_key }; let key = Key::Secret(secret); round_trip(&key); diff --git a/cmd/soroban-cli/src/config/secret.rs b/cmd/soroban-cli/src/config/secret.rs index 754097dd60..93630d545b 100644 --- a/cmd/soroban-cli/src/config/secret.rs +++ b/cmd/soroban-cli/src/config/secret.rs @@ -130,7 +130,7 @@ impl FromStr for Secret { impl From for Secret { fn from(value: PrivateKey) -> Self { Secret::SecretKey { - secret_key: format!("{value}"), + secret_key: format!("{}", value.as_unredacted()), } } } @@ -285,7 +285,7 @@ mod tests { assert!(matches!(secret, Secret::SecretKey { .. })); assert_eq!(public_key.to_string(), TEST_PUBLIC_KEY); - assert_eq!(private_key.to_string(), TEST_SECRET_KEY); + assert_eq!(private_key.as_unredacted().to_string(), TEST_SECRET_KEY); } #[test] @@ -296,7 +296,7 @@ mod tests { assert!(matches!(secret, Secret::SeedPhrase { .. })); assert_eq!(public_key.to_string(), TEST_PUBLIC_KEY); - assert_eq!(private_key.to_string(), TEST_SECRET_KEY); + assert_eq!(private_key.as_unredacted().to_string(), TEST_SECRET_KEY); } #[test] @@ -463,7 +463,7 @@ mod tests { let pk = secret.public_key(Some(0)).unwrap(); let sk = secret.private_key(Some(0)).unwrap(); assert_eq!(pk.to_string(), TEST_PUBLIC_KEY); - assert_eq!(sk.to_string(), TEST_SECRET_KEY); + assert_eq!(sk.as_unredacted().to_string(), TEST_SECRET_KEY); } #[test] diff --git a/cmd/soroban-cli/src/utils.rs b/cmd/soroban-cli/src/utils.rs index 49f579cbdb..ddaa959e32 100644 --- a/cmd/soroban-cli/src/utils.rs +++ b/cmd/soroban-cli/src/utils.rs @@ -107,19 +107,7 @@ pub fn lab_url_for_contract( pub fn contract_id_from_str( contract_id: &str, ) -> Result { - Ok( - if let Ok(strkey) = stellar_strkey::Contract::from_string(contract_id) { - strkey - } else { - // strkey failed, try to parse it as a hex string, for backwards compatibility. - stellar_strkey::Contract( - soroban_spec_tools::utils::padded_hex_from_str(contract_id, 32) - .map_err(|_| stellar_strkey::DecodeError::Invalid)? - .try_into() - .map_err(|_| stellar_strkey::DecodeError::Invalid)?, - ) - }, - ) + soroban_spec_tools::utils::contract_id_from_str(contract_id).map(stellar_strkey::Contract) } /// # Errors