Skip to content

Commit 14de539

Browse files
additional-libs feature for keyring and stellar-ledger dependencies (#1977)
* Add an `additional-libs` feature for keyring and stellar-ledger crates * Return an error if a user tries to use a ledger or secure store without additional-libs
1 parent 125a5c1 commit 14de539

15 files changed

Lines changed: 336 additions & 176 deletions

File tree

.github/workflows/binaries.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
5757
- name: Build
5858
run: |
59-
cargo build --package ${{ matrix.crate.name }} --features opt --release --target ${{ matrix.sys.target }}
59+
cargo build --package ${{ matrix.crate.name }} --features opt,additional-libs --release --target ${{ matrix.sys.target }}
6060
- name: Build provenance for binary attestation (release only)
6161
if: github.event_name == 'release'
6262
uses: actions/attest-build-provenance@v2

.github/workflows/ledger-emulator.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ jobs:
2626
sudo apt update && sudo apt install -y libudev-dev libdbus-1-dev
2727
- run: |
2828
cargo test --manifest-path cmd/crates/stellar-ledger/Cargo.toml --features "emulator-tests" -- --nocapture
29-
- run: cargo build --features emulator-tests
29+
- run: cargo build --features emulator-tests,additional-libs
3030
- run: |
3131
cargo test --features emulator-tests --package soroban-test --test it -- emulator

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ generate-full-help-doc:
4949

5050
test: build-test
5151
cargo test --workspace --exclude soroban-test
52+
cargo test --workspace --exclude soroban-test --features additional-libs
5253
cargo test -p soroban-test -- --skip integration::
5354

5455
e2e-test:

cmd/soroban-cli/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ version_lt_23 = []
4040
version_gte_23 = []
4141
opt = ["dep:wasm-opt"]
4242
emulator-tests = ["stellar-ledger/emulator-tests"]
43+
additional-libs = ["dep:keyring", "dep:stellar-ledger"]
4344

4445
[dependencies]
4546
stellar-xdr = { workspace = true, features = ["cli"] }
@@ -52,7 +53,7 @@ soroban-ledger-snapshot = { workspace = true }
5253
stellar-strkey = { workspace = true }
5354
soroban-sdk = { workspace = true }
5455
soroban-rpc = { workspace = true }
55-
stellar-ledger = { workspace = true }
56+
stellar-ledger = { workspace = true, optional = true }
5657

5758
clap = { workspace = true, features = [
5859
"derive",
@@ -131,7 +132,7 @@ open = "5.3.0"
131132
url = "2.5.2"
132133
wasm-gen = "0.1.4"
133134
zeroize = "1.8.1"
134-
keyring = { version = "3", features = ["apple-native", "windows-native", "sync-secret-service"] }
135+
keyring = { version = "3", features = ["apple-native", "windows-native", "sync-secret-service"], optional = true }
135136
whoami = "1.5.2"
136137
serde_with = "3.11.0"
137138

cmd/soroban-cli/src/commands/keys/add.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ impl Cmd {
8181

8282
let seed_phrase: SeedPhrase = secret_key.parse()?;
8383

84-
Ok(secure_store::save_secret(print, &self.name, seed_phrase)?)
84+
let secret = secure_store::save_secret(print, &self.name, &seed_phrase)?;
85+
Ok(secret.parse()?)
8586
} else {
8687
let prompt = "Type a secret key or 12/24 word seed phrase:";
8788
let secret_key = read_password(print, prompt)?;

cmd/soroban-cli/src/commands/keys/generate.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ impl Cmd {
127127
fn secret(&self, print: &Print) -> Result<Secret, Error> {
128128
let seed_phrase = self.seed_phrase()?;
129129
if self.secure_store {
130-
Ok(secure_store::save_secret(print, &self.name, seed_phrase)?)
130+
let secret = secure_store::save_secret(print, &self.name, &seed_phrase)?;
131+
Ok(secret.parse()?)
131132
} else if self.as_secret {
132133
let secret: Secret = seed_phrase.into();
133134
Ok(secret.private_key(self.hd_path)?.into())
@@ -144,7 +145,6 @@ impl Cmd {
144145
#[cfg(test)]
145146
mod tests {
146147
use crate::config::{address::KeyName, key::Key, secret::Secret};
147-
use keyring::{mock, set_default_credential_builder};
148148

149149
fn set_up_test() -> (super::locator::Args, super::Cmd) {
150150
let temp_dir = tempfile::tempdir().unwrap();
@@ -200,8 +200,10 @@ mod tests {
200200
assert!(matches!(identity, Key::Secret(Secret::SecretKey { .. })));
201201
}
202202

203+
#[cfg(feature = "additional-libs")]
203204
#[tokio::test]
204205
async fn test_storing_secret_in_secure_store() {
206+
use keyring::{mock, set_default_credential_builder};
205207
set_default_credential_builder(mock::default_credential_builder());
206208
let (test_locator, mut cmd) = set_up_test();
207209
cmd.secure_store = true;
@@ -212,4 +214,26 @@ mod tests {
212214
let identity = test_locator.read_identity("test_name").unwrap();
213215
assert!(matches!(identity, Key::Secret(Secret::SecureStore { .. })));
214216
}
217+
218+
#[cfg(not(feature = "additional-libs"))]
219+
#[tokio::test]
220+
async fn test_storing_in_secure_store_returns_error_when_additional_libs_not_enabled() {
221+
let (test_locator, mut cmd) = set_up_test();
222+
cmd.secure_store = true;
223+
let global_args = global_args();
224+
225+
let result = cmd.run(&global_args).await;
226+
assert!(result.is_err());
227+
assert_eq!(
228+
result.unwrap_err().to_string(),
229+
format!("Secure Store keys are not allowed: additional-libs feature must be enabled")
230+
);
231+
232+
let identity_result = test_locator.read_identity("test_name");
233+
assert!(identity_result.is_err());
234+
assert_eq!(
235+
identity_result.unwrap_err().to_string(),
236+
format!("Failed to find config identity for test_name")
237+
);
238+
}
215239
}

cmd/soroban-cli/src/config/address.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ pub enum Error {
4848
InvalidKeyName(String),
4949
#[error("Ledger not supported in this context")]
5050
LedgerNotSupported,
51+
#[error(transparent)]
52+
Ledger(#[from] signer::ledger::Error),
5153
}
5254

5355
impl FromStr for UnresolvedMuxedAccount {
@@ -85,7 +87,7 @@ impl UnresolvedMuxedAccount {
8587
) -> Result<xdr::MuxedAccount, Error> {
8688
match self {
8789
UnresolvedMuxedAccount::Ledger(hd_path) => Ok(xdr::MuxedAccount::Ed25519(
88-
ledger(*hd_path).await?.public_key().await?.0.into(),
90+
ledger::new(*hd_path).await?.public_key().await?.0.into(),
8991
)),
9092
UnresolvedMuxedAccount::Resolved(_) | UnresolvedMuxedAccount::AliasOrSecret(_) => {
9193
self.resolve_muxed_account_sync(locator, hd_path)

cmd/soroban-cli/src/config/locator.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use stellar_strkey::{Contract, DecodeError};
1515
use crate::{
1616
commands::{global, HEADING_GLOBAL},
1717
print::Print,
18-
signer::{self, keyring::StellarEntry},
18+
signer::secure_store,
1919
utils::find_config_dir,
2020
xdr, Pwd,
2121
};
@@ -95,7 +95,7 @@ pub enum Error {
9595
#[error("Key cannot {0} cannot overlap with contract alias")]
9696
KeyCannotOverlapWithContractAlias(String),
9797
#[error(transparent)]
98-
Keyring(#[from] signer::keyring::Error),
98+
SecureStore(#[from] secure_store::Error),
9999
#[error("Only private keys and seed phrases are supported for getting private keys {0}")]
100100
SecretKeyOnly(String),
101101
#[error(transparent)]
@@ -301,20 +301,10 @@ impl Args {
301301
let identity = self.read_identity(name)?;
302302

303303
if let Key::Secret(Secret::SecureStore { entry_name }) = identity {
304-
let entry = StellarEntry::new(&entry_name)?;
305-
match entry.delete_seed_phrase() {
306-
Ok(()) => {}
307-
Err(e) => match e {
308-
signer::keyring::Error::Keyring(keyring::Error::NoEntry) => {
309-
print.infoln("This key was already removed from the secure store. Removing the cli config file.");
310-
}
311-
_ => {
312-
return Err(Error::Keyring(e));
313-
}
314-
},
315-
}
304+
secure_store::delete_secret(&print, &entry_name)?;
316305
}
317306

307+
print.infoln("Removing the key's cli config file");
318308
KeyType::Identity.remove(name, &self.config_dir()?)
319309
}
320310

cmd/soroban-cli/src/config/secret.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use stellar_strkey::ed25519::{PrivateKey, PublicKey};
77

88
use crate::{
99
print::Print,
10-
signer::{self, keyring, ledger, LocalKey, SecureStoreEntry, Signer, SignerKind},
10+
signer::{self, ledger, secure_store, LocalKey, SecureStoreEntry, Signer, SignerKind},
1111
utils,
1212
};
1313

@@ -25,14 +25,14 @@ pub enum Error {
2525
InvalidSecretOrSeedPhrase,
2626
#[error(transparent)]
2727
Signer(#[from] signer::Error),
28-
2928
#[error("Ledger does not reveal secret key")]
3029
LedgerDoesNotRevealSecretKey,
31-
3230
#[error(transparent)]
33-
Keyring(#[from] keyring::Error),
31+
SecureStore(#[from] secure_store::Error),
3432
#[error("Secure Store does not reveal secret key")]
3533
SecureStoreDoesNotRevealSecretKey,
34+
#[error(transparent)]
35+
Ledger(#[from] signer::ledger::Error),
3636
}
3737

3838
#[derive(Debug, clap::Args, Clone)]
@@ -72,7 +72,7 @@ impl FromStr for Secret {
7272
})
7373
} else if s == "ledger" {
7474
Ok(Secret::Ledger)
75-
} else if s.starts_with(keyring::SECURE_STORE_ENTRY_PREFIX) {
75+
} else if s.starts_with(secure_store::ENTRY_PREFIX) {
7676
Ok(Secret::SecureStore {
7777
entry_name: s.to_string(),
7878
})
@@ -123,8 +123,7 @@ impl Secret {
123123

124124
pub fn public_key(&self, index: Option<usize>) -> Result<PublicKey, Error> {
125125
if let Secret::SecureStore { entry_name } = self {
126-
let entry = keyring::StellarEntry::new(entry_name)?;
127-
Ok(entry.get_public_key(index)?)
126+
Ok(secure_store::get_public_key(entry_name, index)?)
128127
} else {
129128
let key = self.key_pair(index)?;
130129
Ok(stellar_strkey::ed25519::PublicKey::from_payload(
@@ -144,7 +143,7 @@ impl Secret {
144143
.unwrap_or_default()
145144
.try_into()
146145
.expect("uszie bigger than u32");
147-
SignerKind::Ledger(ledger(hd_path).await?)
146+
SignerKind::Ledger(ledger::new(hd_path).await?)
148147
}
149148
Secret::SecureStore { entry_name } => SignerKind::SecureStore(SecureStoreEntry {
150149
name: entry_name.to_string(),

cmd/soroban-cli/src/config/sign_with.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub enum Error {
2929
StrKey(#[from] stellar_strkey::DecodeError),
3030
#[error(transparent)]
3131
Xdr(#[from] xdr::Error),
32+
#[error(transparent)]
33+
Ledger(#[from] signer::ledger::Error),
3234
}
3335

3436
#[derive(Debug, clap::Args, Clone, Default)]
@@ -72,7 +74,7 @@ impl Args {
7274
print,
7375
}
7476
} else if self.sign_with_ledger {
75-
let ledger = ledger(
77+
let ledger = ledger::new(
7678
self.hd_path
7779
.unwrap_or_default()
7880
.try_into()

0 commit comments

Comments
 (0)