Skip to content

Commit

Permalink
Merge branch 'feat/tx_sign' into feat/sign_with_lab
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmcculloch committed Sep 24, 2024
2 parents 9edbfb6 + 1db4b5a commit d2300cb
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 55 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ endif
REPOSITORY_BRANCH := "$(shell git rev-parse --abbrev-ref HEAD)"
BUILD_TIMESTAMP ?= $(shell date '+%Y-%m-%dT%H:%M:%S')

SOROBAN_PORT?=8000

# The following works around incompatibility between the rust and the go linkers -
# the rust would generate an object file with min-version of 13.0 where-as the go
# compiler would generate a binary compatible with 12.3 and up. To align these
Expand Down Expand Up @@ -53,7 +55,7 @@ test: build-test
cargo test

e2e-test:
cargo test --test it -- --ignored
cargo test --features it --test it -- integration

check:
cargo clippy --all-targets
Expand Down
49 changes: 17 additions & 32 deletions cmd/crates/soroban-test/tests/it/integration/tx.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use soroban_rpc::GetTransactionResponse;
use soroban_sdk::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr};
use soroban_test::{AssertExt, TestEnv};

use crate::integration::util::{deploy_contract, deploy_hello, DeployKind, HELLO_WORLD};
use crate::integration::util::{deploy_contract, DeployKind, HELLO_WORLD};

#[tokio::test]
async fn simulate() {
Expand Down Expand Up @@ -52,7 +51,7 @@ async fn txn_hash() {
}

#[tokio::test]
async fn send() {
async fn build_simulate_sign_send() {
let sandbox = &TestEnv::new();
sandbox
.new_assert_cmd("contract")
Expand All @@ -61,36 +60,22 @@ async fn send() {
.assert()
.success();

let xdr_base64 = deploy_contract(sandbox, HELLO_WORLD, DeployKind::SimOnly).await;
println!("{xdr_base64}");
let tx_env = TransactionEnvelope::from_xdr_base64(&xdr_base64, Limits::none()).unwrap();
let tx_env = sign_manually(sandbox, &tx_env);
let tx_simulated = deploy_contract(sandbox, HELLO_WORLD, DeployKind::SimOnly).await;
dbg!("{tx_simulated}");

println!(
"Transaction to send:\n{}",
tx_env.to_xdr_base64(Limits::none()).unwrap()
);

let rpc_result = send_manually(sandbox, &tx_env).await;
assert_eq!(rpc_result.status, "SUCCESS");
}
let tx_signed = sandbox
.new_assert_cmd("tx")
.arg("sign")
.arg("--sign-with-key=test")
.write_stdin(tx_simulated.as_bytes())
.assert()
.success()
.stdout_as_str();
dbg!("{tx_signed}");

async fn send_manually(sandbox: &TestEnv, tx_env: &TransactionEnvelope) -> GetTransactionResponse {
// TODO: Replace with calling tx send when that command is added.
let tx_signed = TransactionEnvelope::from_xdr_base64(tx_signed, Limits::none()).unwrap();
let client = soroban_rpc::Client::new(&sandbox.rpc_url).unwrap();
client.send_transaction_polling(tx_env).await.unwrap()
}

fn sign_manually(sandbox: &TestEnv, tx_env: &TransactionEnvelope) -> TransactionEnvelope {
TransactionEnvelope::from_xdr_base64(
sandbox
.new_assert_cmd("tx")
.arg("sign")
.arg("--sign-with-key=test")
.write_stdin(tx_env.to_xdr_base64(Limits::none()).unwrap().as_bytes())
.assert()
.success()
.stdout_as_str(),
Limits::none(),
)
.unwrap()
let rpc_result = client.send_transaction_polling(&tx_signed).await.unwrap();
assert_eq!(rpc_result.status, "SUCCESS");
}
2 changes: 1 addition & 1 deletion cmd/soroban-cli/src/commands/tx/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl Cmd {
&self.network.get(&self.locator)?,
global_args.quiet,
)?;
println!("{}", tx_env_signed.to_xdr_base64(Limits::none())?.trim());
println!("{}", tx_env_signed.to_xdr_base64(Limits::none())?);
Ok(())
}
}
2 changes: 1 addition & 1 deletion cmd/soroban-cli/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl Args {
let key = self.key_pair()?;
let network = &self.get_network()?;
let signer = Signer {
kind: SignerKind::Local(LocalKey::new(key, false)),
kind: SignerKind::Local(LocalKey { key }),
printer: Print::new(false),
};
Ok(signer.sign_tx(tx, network)?)
Expand Down
5 changes: 3 additions & 2 deletions cmd/soroban-cli/src/config/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ impl Secret {
)?)
}

pub fn signer(&self, index: Option<usize>, prompt: bool, quiet: bool) -> Result<Signer, Error> {
pub fn signer(&self, index: Option<usize>, quiet: bool) -> Result<Signer, Error> {
let kind = match self {
Secret::SecretKey { .. } | Secret::SeedPhrase { .. } => {
SignerKind::Local(LocalKey::new(self.key_pair(index)?, prompt))
let key = self.key_pair(index)?;
SignerKind::Local(LocalKey { key })
}
};
Ok(Signer {
Expand Down
12 changes: 7 additions & 5 deletions cmd/soroban-cli/src/config/sign_with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ pub enum Error {
#[group(skip)]
pub struct Args {
/// Sign with a local key. Can be an identity (--sign-with-key alice), a secret key (--sign-with-key SC36…), or a seed phrase (--sign-with-key "kite urban…"). If using seed phrase, `--hd-path` defaults to the `0` path.
#[arg(long, conflicts_with = "sign_with_lab", env = "STELLAR_SIGN_WITH_KEY")]
#[arg(long, env = "STELLAR_SIGN_WITH_KEY")]
pub sign_with_key: Option<String>,
/// Sign with <https://lab.stellar.org>
#[arg(long, conflicts_with = "sign_with_key", env = "STELLAR_SIGN_WITH_LAB")]
pub sign_with_lab: bool,

#[arg(long, conflicts_with = "sign_with_lab")]
/// If using a seed phrase to sign, sets which hierarchical deterministic path to use, e.g. `m/44'/148'/{hd_path}`. Example: `--hd-path 1`. Default: `0`
pub hd_path: Option<usize>,

/// Sign with <https://lab.stellar.org>
#[arg(long, conflicts_with = "sign_with_key", env = "STELLAR_SIGN_WITH_LAB")]
pub sign_with_lab: bool,
}

impl Args {
Expand All @@ -60,7 +62,7 @@ impl Args {
) -> Result<TransactionEnvelope, Error> {
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)?;
let signer = secret.signer(self.hd_path, quiet)?;
Ok(signer.sign_tx_env(tx, network)?)
}
pub fn sign_tx_env_with_lab(
Expand Down
16 changes: 3 additions & 13 deletions cmd/soroban-cli/src/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,8 @@ impl Signer {
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)
));
self.printer
.infoln(format!("Signing transaction: {}", hex::encode(tx_hash),));
let decorated_signature = match &self.kind {
SignerKind::Local(key) => key.sign_tx_hash(tx_hash)?,
};
Expand All @@ -243,15 +241,7 @@ impl Signer {
}

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 }
}
pub key: ed25519_dalek::SigningKey,
}

impl LocalKey {
Expand Down

0 comments on commit d2300cb

Please sign in to comment.