Skip to content

Commit

Permalink
feat: remove stellar-ledger
Browse files Browse the repository at this point in the history
  • Loading branch information
willemneal committed Jun 26, 2024
1 parent b82468e commit abf291a
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 96 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 13 additions & 8 deletions cmd/crates/stellar-ledger/src/hd_path.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::Error;

#[derive(Clone, Copy)]
pub struct HdPath(pub u32);

impl HdPath {
#[must_use]
pub fn depth(&self) -> u8 {
let path: slip10::BIP32Path = self.into();
path.depth()
Expand All @@ -22,8 +23,7 @@ impl From<&u32> for HdPath {
}

impl HdPath {
#[must_use]
pub fn to_vec(&self) -> Vec<u8> {
pub fn to_vec(&self) -> Result<Vec<u8>, Error> {
hd_path_to_bytes(&self.into())
}
}
Expand All @@ -35,11 +35,16 @@ impl From<&HdPath> for slip10::BIP32Path {
}
}

fn hd_path_to_bytes(hd_path: &slip10::BIP32Path) -> Vec<u8> {
fn hd_path_to_bytes(hd_path: &slip10::BIP32Path) -> Result<Vec<u8>, Error> {
let hd_path_indices = 0..hd_path.depth();
// Unsafe unwrap is safe because the depth is the length of interneal vector
hd_path_indices
let result = hd_path_indices
.into_iter()
.flat_map(|index| unsafe { hd_path.index(index).unwrap_unchecked().to_be_bytes() })
.collect()
.map(|index| {
Ok(hd_path
.index(index)
.ok_or_else(|| Error::Bip32PathError(format!("{hd_path}")))?
.to_be_bytes())
})
.collect::<Result<Vec<_>, Error>>()?;
Ok(result.into_iter().flatten().collect())
}
69 changes: 28 additions & 41 deletions cmd/crates/stellar-ledger/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use hd_path::HdPath;
use ledger_transport::APDUCommand;
pub use ledger_transport_hid::TransportNativeHID;
use ledger_transport::{APDUCommand, Exchange};
use ledger_transport_hid::{
hidapi::{HidApi, HidError},
LedgerHIDError,
LedgerHIDError, TransportNativeHID,
};

use soroban_env_host::xdr::{Hash, Transaction};
Expand All @@ -16,8 +15,6 @@ use stellar_xdr::curr::{

pub use crate::signer::Blob;
pub mod hd_path;
pub use ledger_transport::Exchange;

mod signer;

// this is from https://github.com/LedgerHQ/ledger-live/blob/36cfbf3fa3300fd99bcee2ab72e1fd8f280e6280/libs/ledgerjs/packages/hw-app-str/src/Str.ts#L181
Expand Down Expand Up @@ -83,11 +80,6 @@ pub struct LedgerSigner<T: Exchange> {
unsafe impl<T> Send for LedgerSigner<T> where T: Exchange {}
unsafe impl<T> Sync for LedgerSigner<T> where T: Exchange {}

/// Returns a new `LedgerSigner` with a native HID transport, e.i. the transport is connected to the Ledger device
///
/// # Errors
///
/// Returns an error if there is an issue with connecting with the device
pub fn native() -> Result<LedgerSigner<TransportNativeHID>, Error> {
Ok(LedgerSigner {
transport: get_transport()?,
Expand All @@ -101,7 +93,11 @@ where
pub fn new(transport: T) -> Self {
Self { transport }
}

pub fn native() -> Result<LedgerSigner<TransportNativeHID>, Error> {
Ok(LedgerSigner {
transport: get_transport()?,
})
}
/// Get the device app's configuration
/// # Errors
/// Returns an error if there is an issue with connecting with the device or getting the config from the device
Expand Down Expand Up @@ -145,7 +141,7 @@ where
};
let mut signature_payload_as_bytes = signature_payload.to_xdr(Limits::none())?;

let mut hd_path_to_bytes = hd_path.into().to_vec();
let mut hd_path_to_bytes = hd_path.into().to_vec()?;

let capacity = 1 + hd_path_to_bytes.len() + signature_payload_as_bytes.len();
let mut data: Vec<u8> = Vec::with_capacity(capacity);
Expand Down Expand Up @@ -186,9 +182,7 @@ where
}

/// The `display_and_confirm` bool determines if the Ledger will display the public key on its screen and requires user approval to share
/// # Errors
/// Returns an error if there is an issue with connecting with the device or getting the public key from the device
pub async fn get_public_key_with_display_flag(
async fn get_public_key_with_display_flag(
&self,
hd_path: impl Into<HdPath>,
display_and_confirm: bool,
Expand All @@ -197,7 +191,7 @@ where
// the first element of the data should be the number of elements in the path
let hd_path = hd_path.into();
let hd_path_elements_count = hd_path.depth();
let mut hd_path_to_bytes = hd_path.to_vec();
let mut hd_path_to_bytes = hd_path.to_vec()?;
hd_path_to_bytes.insert(0, hd_path_elements_count);

let p2 = if display_and_confirm {
Expand Down Expand Up @@ -247,30 +241,6 @@ where
)),
}
}

/// Sign a blob of data with the account on the Ledger device
/// # Errors
/// Returns an error if there is an issue with connecting with the device or signing the given tx on the device
pub async fn sign_data(&self, index: &HdPath, blob: &[u8]) -> Result<Vec<u8>, Error> {
let mut hd_path_to_bytes = index.to_vec();

let capacity = 1 + hd_path_to_bytes.len() + blob.len();
let mut data: Vec<u8> = Vec::with_capacity(capacity);

data.insert(0, HD_PATH_ELEMENTS_COUNT);
data.append(&mut hd_path_to_bytes);
data.extend_from_slice(blob);

let command = APDUCommand {
cla: CLA,
ins: SIGN_TX_HASH,
p1: P1_SIGN_TX_HASH,
p2: P2_SIGN_TX_HASH,
data,
};

self.send_command_to_ledger(command).await
}
}

#[async_trait::async_trait]
Expand All @@ -295,7 +265,24 @@ where
/// # Errors
/// Returns an error if there is an issue with connecting with the device or signing the given tx on the device. Or, if the device has not enabled hash signing
async fn sign_blob(&self, index: &Self::Key, blob: &[u8]) -> Result<Vec<u8>, Error> {
self.sign_data(index, blob).await
let mut hd_path_to_bytes = index.to_vec()?;

let capacity = 1 + hd_path_to_bytes.len() + blob.len();
let mut data: Vec<u8> = Vec::with_capacity(capacity);

data.insert(0, HD_PATH_ELEMENTS_COUNT);
data.append(&mut hd_path_to_bytes);
data.extend_from_slice(blob);

let command = APDUCommand {
cla: CLA,
ins: SIGN_TX_HASH,
p1: P1_SIGN_TX_HASH,
p2: P2_SIGN_TX_HASH,
data,
};

self.send_command_to_ledger(command).await
}
}

Expand Down
1 change: 0 additions & 1 deletion cmd/soroban-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ soroban-ledger-snapshot = { workspace = true }
stellar-strkey = { workspace = true }
soroban-sdk = { workspace = true }
soroban-rpc = { workspace = true }
stellar-ledger = { workspace = true }

clap = { workspace = true, features = [
"derive",
Expand Down
18 changes: 2 additions & 16 deletions cmd/soroban-cli/src/commands/config/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{io::Write, str::FromStr};
use stellar_strkey::ed25519::{PrivateKey, PublicKey};

use crate::{
signer::{self, native, Ledger, LocalKey, Stellar},
signer::{self, LocalKey, Stellar},
utils,
};

Expand Down Expand Up @@ -79,7 +79,6 @@ impl Args {
pub enum SignerKind {
SecretKey { secret_key: String },
SeedPhrase { seed_phrase: String },
Ledger,
}

impl FromStr for SignerKind {
Expand All @@ -94,8 +93,6 @@ impl FromStr for SignerKind {
Ok(SignerKind::SeedPhrase {
seed_phrase: s.to_string(),
})
} else if s == "ledger" {
Ok(SignerKind::Ledger)
} else {
Err(Error::InvalidAddress(s.to_string()))
}
Expand All @@ -120,7 +117,6 @@ impl SignerKind {
.private()
.0,
)?,
SignerKind::Ledger => panic!("Ledger does not reveal secret key"),
})
}

Expand All @@ -133,14 +129,7 @@ impl SignerKind {
match self {
SignerKind::SecretKey { .. } | SignerKind::SeedPhrase { .. } => Ok(
StellarSigner::Local(LocalKey::new(self.key_pair(index)?, prompt)),
),
SignerKind::Ledger => {
let hd_path: u32 = index
.unwrap_or_default()
.try_into()
.expect("uszie bigger than u32");
Ok(StellarSigner::Ledger(native(hd_path)?))
}
)
}
}

Expand All @@ -166,21 +155,18 @@ impl SignerKind {

pub enum StellarSigner {
Local(LocalKey),
Ledger(Ledger<stellar_ledger::TransportNativeHID>),
}

impl Stellar for StellarSigner {
async fn get_public_key(&self) -> Result<stellar_strkey::ed25519::PublicKey, signer::Error> {
match self {
StellarSigner::Local(signer) => signer.get_public_key().await,
StellarSigner::Ledger(signer) => signer.get_public_key().await,
}
}

async fn sign_blob(&self, blob: &[u8]) -> Result<Vec<u8>, signer::Error> {
match self {
StellarSigner::Local(signer) => signer.sign_blob(blob).await,
StellarSigner::Ledger(signer) => signer.sign_blob(blob).await,
}
}
}
Expand Down
30 changes: 1 addition & 29 deletions cmd/soroban-cli/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::xdr::{
TransactionSignaturePayload, TransactionSignaturePayloadTaggedTransaction,
TransactionV1Envelope, Uint256, WriteXdr,
};
use stellar_ledger::{Exchange, LedgerSigner};


#[derive(thiserror::Error, Debug)]
pub enum Error {
Expand All @@ -21,8 +21,6 @@ pub enum Error {
#[error("Missing signing key for account {address}")]
MissingSignerForAddress { address: String },
#[error(transparent)]
Ledger(#[from] stellar_ledger::Error),
#[error(transparent)]
Xdr(#[from] xdr::Error),
#[error("User cancelled signing, perhaps need to remove --check")]
UserCancelledSigning,
Expand Down Expand Up @@ -248,32 +246,6 @@ impl Stellar for LocalKey {
}
}

pub struct Ledger<T: Exchange> {
index: u32,
signer: LedgerSigner<T>,
}

pub fn native(index: u32) -> Result<Ledger<stellar_ledger::TransportNativeHID>, Error> {
let signer = stellar_ledger::native()?;
Ok(Ledger { index, signer })
}

impl<T> Stellar for Ledger<T>
where
T: Exchange,
{
async fn get_public_key(&self) -> Result<stellar_strkey::ed25519::PublicKey, Error> {
Ok(self
.signer
.get_public_key_with_display_flag(self.index, false)
.await?)
}

async fn sign_blob(&self, blob: &[u8]) -> Result<Vec<u8>, Error> {
Ok(self.signer.sign_data(&self.index.into(), blob).await?)
}
}

pub fn read_key() -> char {
let tty = get_tty().unwrap();
if let Some(key) = tty.keys().next() {
Expand Down

0 comments on commit abf291a

Please sign in to comment.