diff --git a/cmd/soroban-cli/src/commands/contract/deploy/asset.rs b/cmd/soroban-cli/src/commands/contract/deploy/asset.rs
index 51baa55e9..da7b6b805 100644
--- a/cmd/soroban-cli/src/commands/contract/deploy/asset.rs
+++ b/cmd/soroban-cli/src/commands/contract/deploy/asset.rs
@@ -97,11 +97,10 @@ impl NetworkRunnable for Cmd {
         client
             .verify_network_passphrase(Some(&network.network_passphrase))
             .await?;
-        let key = config.key_pair()?;
+        let key = config.source_account()?;
 
         // Get the account sequence number
-        let public_strkey =
-            stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
+        let public_strkey = key.to_string();
         // TODO: use symbols for the method names (both here and in serve)
         let account_details = client.get_account(&public_strkey).await?;
         let sequence: i64 = account_details.seq_num.into();
@@ -141,7 +140,7 @@ fn build_wrap_token_tx(
     sequence: i64,
     fee: u32,
     _network_passphrase: &str,
-    key: &ed25519_dalek::SigningKey,
+    key: &stellar_strkey::ed25519::PublicKey,
 ) -> Result<Transaction, Error> {
     let contract = ScAddress::Contract(contract_id.clone());
     let mut read_write = vec![
@@ -180,7 +179,7 @@ fn build_wrap_token_tx(
     };
 
     Ok(Transaction {
-        source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
+        source_account: MuxedAccount::Ed25519(Uint256(key.0)),
         fee,
         seq_num: SequenceNumber(sequence),
         cond: Preconditions::None,
diff --git a/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs b/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs
index 74491249f..84138d432 100644
--- a/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs
+++ b/cmd/soroban-cli/src/commands/contract/deploy/wasm.rs
@@ -212,12 +212,10 @@ impl NetworkRunnable for Cmd {
         client
             .verify_network_passphrase(Some(&network.network_passphrase))
             .await?;
-        let key = config.key_pair()?;
+        let key = config.source_account()?;
 
         // Get the account sequence number
-        let public_strkey =
-            stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
-
+        let public_strkey = key.to_string();
         let account_details = client.get_account(&public_strkey).await?;
         let sequence: i64 = account_details.seq_num.into();
         let (txn, contract_id) = build_create_contract_tx(
@@ -274,11 +272,9 @@ fn build_create_contract_tx(
     fee: u32,
     network_passphrase: &str,
     salt: [u8; 32],
-    key: &ed25519_dalek::SigningKey,
+    key: &stellar_strkey::ed25519::PublicKey,
 ) -> Result<(Transaction, Hash), Error> {
-    let source_account = AccountId(PublicKey::PublicKeyTypeEd25519(
-        key.verifying_key().to_bytes().into(),
-    ));
+    let source_account = AccountId(PublicKey::PublicKeyTypeEd25519(key.0.into()));
 
     let contract_id_preimage = ContractIdPreimage::Address(ContractIdPreimageFromAddress {
         address: ScAddress::Account(source_account),
@@ -297,7 +293,7 @@ fn build_create_contract_tx(
         }),
     };
     let tx = Transaction {
-        source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
+        source_account: MuxedAccount::Ed25519(Uint256(key.0)),
         fee,
         seq_num: SequenceNumber(sequence),
         cond: Preconditions::None,
@@ -325,8 +321,12 @@ mod tests {
             1,
             "Public Global Stellar Network ; September 2015",
             [0u8; 32],
-            &utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
-                .unwrap(),
+            &stellar_strkey::ed25519::PublicKey(
+                utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
+                    .unwrap()
+                    .verifying_key()
+                    .to_bytes(),
+            ),
         );
 
         assert!(result.is_ok());
diff --git a/cmd/soroban-cli/src/commands/contract/extend.rs b/cmd/soroban-cli/src/commands/contract/extend.rs
index 5901c71b1..6666fcce7 100644
--- a/cmd/soroban-cli/src/commands/contract/extend.rs
+++ b/cmd/soroban-cli/src/commands/contract/extend.rs
@@ -132,17 +132,15 @@ impl NetworkRunnable for Cmd {
         tracing::trace!(?network);
         let keys = self.key.parse_keys(&config.locator, &network)?;
         let client = Client::new(&network.rpc_url)?;
-        let key = config.key_pair()?;
+        let key = config.source_account()?;
         let extend_to = self.ledgers_to_extend();
 
         // Get the account sequence number
-        let public_strkey =
-            stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
-        let account_details = client.get_account(&public_strkey).await?;
+        let account_details = client.get_account(&key.to_string()).await?;
         let sequence: i64 = account_details.seq_num.into();
 
         let tx = Transaction {
-            source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
+            source_account: MuxedAccount::Ed25519(Uint256(key.0)),
             fee: self.fee.fee,
             seq_num: SequenceNumber(sequence + 1),
             cond: Preconditions::None,
diff --git a/cmd/soroban-cli/src/commands/contract/install.rs b/cmd/soroban-cli/src/commands/contract/install.rs
index 98c866271..5a1842b7b 100644
--- a/cmd/soroban-cli/src/commands/contract/install.rs
+++ b/cmd/soroban-cli/src/commands/contract/install.rs
@@ -126,16 +126,14 @@ impl NetworkRunnable for Cmd {
             }
         }
 
-        let key = config.key_pair()?;
-
         // Get the account sequence number
-        let public_strkey =
-            stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
-        let account_details = client.get_account(&public_strkey).await?;
+        let source_account = config.source_account()?;
+
+        let account_details = client.get_account(&source_account.to_string()).await?;
         let sequence: i64 = account_details.seq_num.into();
 
         let (tx_without_preflight, hash) =
-            build_install_contract_code_tx(&contract, sequence + 1, self.fee.fee, &key)?;
+            build_install_contract_code_tx(&contract, sequence + 1, self.fee.fee, &source_account)?;
 
         if self.fee.build_only {
             return Ok(TxnResult::Txn(tx_without_preflight));
@@ -255,14 +253,12 @@ pub(crate) fn build_install_contract_code_tx(
     source_code: &[u8],
     sequence: i64,
     fee: u32,
-    key: &ed25519_dalek::SigningKey,
+    key: &stellar_strkey::ed25519::PublicKey,
 ) -> Result<(Transaction, Hash), XdrError> {
     let hash = utils::contract_hash(source_code)?;
 
     let op = Operation {
-        source_account: Some(MuxedAccount::Ed25519(Uint256(
-            key.verifying_key().to_bytes(),
-        ))),
+        source_account: Some(MuxedAccount::Ed25519(Uint256(key.0))),
         body: OperationBody::InvokeHostFunction(InvokeHostFunctionOp {
             host_function: HostFunction::UploadContractWasm(source_code.try_into()?),
             auth: VecM::default(),
@@ -270,7 +266,7 @@ pub(crate) fn build_install_contract_code_tx(
     };
 
     let tx = Transaction {
-        source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
+        source_account: MuxedAccount::Ed25519(Uint256(key.0)),
         fee,
         seq_num: SequenceNumber(sequence),
         cond: Preconditions::None,
@@ -292,8 +288,13 @@ mod tests {
             b"foo",
             300,
             1,
-            &utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
-                .unwrap(),
+            &stellar_strkey::ed25519::PublicKey::from_payload(
+                utils::parse_secret_key("SBFGFF27Y64ZUGFAIG5AMJGQODZZKV2YQKAVUUN4HNE24XZXD2OEUVUP")
+                    .unwrap()
+                    .verifying_key()
+                    .as_bytes(),
+            )
+            .unwrap(),
         );
 
         assert!(result.is_ok());
diff --git a/cmd/soroban-cli/src/commands/contract/invoke.rs b/cmd/soroban-cli/src/commands/contract/invoke.rs
index 293867c76..fa90ef9b3 100644
--- a/cmd/soroban-cli/src/commands/contract/invoke.rs
+++ b/cmd/soroban-cli/src/commands/contract/invoke.rs
@@ -216,12 +216,10 @@ impl NetworkRunnable for Cmd {
             client
                 .verify_network_passphrase(Some(&network.network_passphrase))
                 .await?;
-            let key = config.key_pair()?;
 
-            // Get the account sequence number
-            let public_strkey =
-                stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
-            client.get_account(&public_strkey).await?
+            client
+                .get_account(&config.source_account()?.to_string())
+                .await?
         };
         let sequence: i64 = account_details.seq_num.into();
         let AccountId(PublicKey::PublicKeyTypeEd25519(account_id)) = account_details.account_id;
diff --git a/cmd/soroban-cli/src/commands/contract/restore.rs b/cmd/soroban-cli/src/commands/contract/restore.rs
index e3e8e65ae..cf6a33248 100644
--- a/cmd/soroban-cli/src/commands/contract/restore.rs
+++ b/cmd/soroban-cli/src/commands/contract/restore.rs
@@ -135,16 +135,15 @@ impl NetworkRunnable for Cmd {
         tracing::trace!(?network);
         let entry_keys = self.key.parse_keys(&config.locator, &network)?;
         let client = Client::new(&network.rpc_url)?;
-        let key = config.key_pair()?;
+        let key = config.source_account()?;
 
         // Get the account sequence number
-        let public_strkey =
-            stellar_strkey::ed25519::PublicKey(key.verifying_key().to_bytes()).to_string();
+        let public_strkey = key.to_string();
         let account_details = client.get_account(&public_strkey).await?;
         let sequence: i64 = account_details.seq_num.into();
 
         let tx = Transaction {
-            source_account: MuxedAccount::Ed25519(Uint256(key.verifying_key().to_bytes())),
+            source_account: MuxedAccount::Ed25519(Uint256(key.0)),
             fee: self.fee.fee,
             seq_num: SequenceNumber(sequence + 1),
             cond: Preconditions::None,
diff --git a/cmd/soroban-cli/src/config/mod.rs b/cmd/soroban-cli/src/config/mod.rs
index 274713e19..511c5a53c 100644
--- a/cmd/soroban-cli/src/config/mod.rs
+++ b/cmd/soroban-cli/src/config/mod.rs
@@ -34,6 +34,8 @@ pub enum Error {
     Rpc(#[from] soroban_rpc::Error),
     #[error(transparent)]
     Signer(#[from] signer::Error),
+    #[error(transparent)]
+    StellarStrkey(#[from] stellar_strkey::DecodeError),
 }
 
 #[derive(Debug, clap::Args, Clone, Default)]
@@ -55,6 +57,19 @@ pub struct Args {
 }
 
 impl Args {
+    // TODO: Replace PublicKey with MuxedAccount once https://github.com/stellar/rs-stellar-xdr/pull/396 is merged.
+    pub fn source_account(&self) -> Result<stellar_strkey::ed25519::PublicKey, Error> {
+        if let Ok(secret) = self.locator.read_identity(&self.source_account) {
+            Ok(stellar_strkey::ed25519::PublicKey(
+                secret.key_pair(self.hd_path)?.verifying_key().to_bytes(),
+            ))
+        } else {
+            Ok(stellar_strkey::ed25519::PublicKey::from_string(
+                &self.source_account,
+            )?)
+        }
+    }
+
     pub fn key_pair(&self) -> Result<ed25519_dalek::SigningKey, Error> {
         let key = self.account(&self.source_account)?;
         Ok(key.key_pair(self.hd_path)?)