Skip to content

Commit

Permalink
move types into signer and replace existing signing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmcculloch committed Sep 23, 2024
1 parent ded7eba commit 015435b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 133 deletions.
15 changes: 6 additions & 9 deletions cmd/soroban-cli/src/commands/tx/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,12 @@ impl Cmd {
#[allow(clippy::unused_async)]
pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
let tx_env = super::xdr::tx_envelope_from_stdin()?;
let tx_env_signed = self
.sign_with
.sign_tx_env(
tx_env,
&self.locator,
&self.network.get(&self.locator)?,
global_args.quiet,
)
.await?;
let tx_env_signed = self.sign_with.sign_tx_env(
tx_env,
&self.locator,
&self.network.get(&self.locator)?,
global_args.quiet,
)?;
println!("{}", tx_env_signed.to_xdr_base64(Limits::none())?.trim());
Ok(())
}
Expand Down
14 changes: 9 additions & 5 deletions cmd/soroban-cli/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ use clap::{arg, command};
use serde::{Deserialize, Serialize};

use soroban_rpc::Client;
use soroban_sdk::xdr::{TransactionV1Envelope, VecM};

use crate::{
signer,
print::Print,
signer::{self, LocalKey, SignerKind, StellarSigner},
xdr::{Transaction, TransactionEnvelope},
Pwd,
};
Expand Down Expand Up @@ -66,10 +68,12 @@ impl Args {
#[allow(clippy::unused_async)]
pub async fn sign(&self, tx: Transaction) -> Result<TransactionEnvelope, Error> {
let key = self.key_pair()?;
let Network {
network_passphrase, ..
} = &self.get_network()?;
Ok(signer::sign_tx(&key, &tx, network_passphrase)?)
let network = &self.get_network()?;
let signer = StellarSigner {
kind: SignerKind::Local(LocalKey::new(key, false)),
printer: Print::new(false),
};
Ok(signer.sign_tx(tx, network)?)
}

pub async fn sign_soroban_authorizations(
Expand Down
11 changes: 4 additions & 7 deletions cmd/soroban-cli/src/config/sign_with.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
use crate::{
signer::{self, types::sign_tx_env},
xdr::TransactionEnvelope,
};
use crate::{signer, xdr::TransactionEnvelope};
use clap::arg;

use super::{
Expand All @@ -15,7 +12,7 @@ pub enum Error {
#[error(transparent)]
Network(#[from] network::Error),
#[error(transparent)]
Signer(#[from] signer::types::Error),
Signer(#[from] signer::Error),
#[error(transparent)]
Secret(#[from] secret::Error),
#[error(transparent)]
Expand Down Expand Up @@ -49,7 +46,7 @@ pub struct Args {
}

impl Args {
pub async fn sign_tx_env(
pub fn sign_tx_env(
&self,
tx: TransactionEnvelope,
locator: &locator::Args,
Expand All @@ -59,6 +56,6 @@ impl Args {
let key_or_name = self.sign_with_key.as_deref().ok_or(Error::NoSignWithKey)?;
let secret = locator.key(key_or_name)?;
let signer = secret.signer(self.hd_path, false, quiet)?;
Ok(sign_tx_env(&signer, tx, network).await?)
Ok(signer.sign_tx_env(tx, network)?)
}
}
88 changes: 69 additions & 19 deletions cmd/soroban-cli/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ use soroban_env_host::xdr::{
InvokeHostFunctionOp, Limits, Operation, OperationBody, PublicKey, ScAddress, ScMap, ScSymbol,
ScVal, Signature, SignatureHint, SorobanAddressCredentials, SorobanAuthorizationEntry,
SorobanAuthorizedFunction, SorobanCredentials, Transaction, TransactionEnvelope,
TransactionV1Envelope, Uint256, WriteXdr,
TransactionV1Envelope, Uint256, VecM, WriteXdr,
};

pub mod types;
use crate::utils::transaction_hash;
pub use types::{LocalKey, SignerKind, StellarSigner};
use crate::{config::network::Network, print::Print, utils::transaction_hash};

#[derive(thiserror::Error, Debug)]
pub enum Error {
Expand All @@ -27,6 +25,8 @@ pub enum Error {
UserCancelledSigning,
#[error(transparent)]
Xdr(#[from] xdr::Error),
#[error("Only Transaction envelope V1 type is supported")]
UnsupportedTransactionEnvelopeType,
}

fn requires_auth(txn: &Transaction) -> Option<xdr::Operation> {
Expand Down Expand Up @@ -192,21 +192,71 @@ fn sign_soroban_authorization_entry(
Ok(auth)
}

pub fn sign_tx(
key: &ed25519_dalek::SigningKey,
tx: &Transaction,
network_passphrase: &str,
) -> Result<TransactionEnvelope, Error> {
let tx_hash = transaction_hash(tx, network_passphrase)?;
let tx_signature = key.sign(&tx_hash);
pub struct StellarSigner {
pub kind: SignerKind,
pub printer: Print,
}

let decorated_signature = DecoratedSignature {
hint: SignatureHint(key.verifying_key().to_bytes()[28..].try_into()?),
signature: Signature(tx_signature.to_bytes().try_into()?),
};
pub enum SignerKind {
Local(LocalKey),
}

impl StellarSigner {
pub fn sign_tx(
&self,
tx: Transaction,
network: &Network,
) -> Result<TransactionEnvelope, Error> {
let tx_env = TransactionEnvelope::Tx(TransactionV1Envelope {
tx,
signatures: VecM::default(),
});
self.sign_tx_env(tx_env, network)
}

pub fn sign_tx_env(
&self,
tx_env: TransactionEnvelope,
network: &Network,
) -> Result<TransactionEnvelope, Error> {
match tx_env {
TransactionEnvelope::Tx(TransactionV1Envelope { tx, signatures }) => {
let tx_hash = transaction_hash(&tx, &network.network_passphrase)?;
self.printer.infoln(format!(
"Signing transaction with hash: {}",
hex::encode(tx_hash)
));
let decorated_signature = match &self.kind {
SignerKind::Local(key) => key.sign_tx_hash(tx_hash)?,
};
let mut sigs = signatures.into_vec();
sigs.push(decorated_signature);
Ok(TransactionEnvelope::Tx(TransactionV1Envelope {
tx,
signatures: sigs.try_into()?,
}))
}
_ => Err(Error::UnsupportedTransactionEnvelopeType),
}
}
}

pub struct LocalKey {
key: ed25519_dalek::SigningKey,
#[allow(dead_code)]
prompt: bool,
}

impl LocalKey {
pub fn new(key: ed25519_dalek::SigningKey, prompt: bool) -> Self {
Self { key, prompt }
}
}

Ok(TransactionEnvelope::Tx(TransactionV1Envelope {
tx: tx.clone(),
signatures: [decorated_signature].try_into()?,
}))
impl LocalKey {
pub fn sign_tx_hash(&self, tx_hash: [u8; 32]) -> Result<DecoratedSignature, Error> {
let hint = SignatureHint(self.key.verifying_key().to_bytes()[28..].try_into()?);
let signature = Signature(self.key.sign(&tx_hash).to_bytes().to_vec().try_into()?);
Ok(DecoratedSignature { hint, signature })
}
}
93 changes: 0 additions & 93 deletions cmd/soroban-cli/src/signer/types.rs

This file was deleted.

0 comments on commit 015435b

Please sign in to comment.