Skip to content

Commit

Permalink
feat: txn commands to sign, simulate, and send txns
Browse files Browse the repository at this point in the history
  • Loading branch information
willemneal committed Apr 15, 2024
1 parent 6ce8006 commit 0443ef2
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 0 deletions.
7 changes: 7 additions & 0 deletions cmd/soroban-cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod keys;
pub mod lab;
pub mod network;
pub mod plugin;
pub mod txn;
pub mod version;

pub mod txn_result;
Expand Down Expand Up @@ -103,6 +104,7 @@ impl Root {
Cmd::Version(version) => version.run(),
Cmd::Keys(id) => id.run().await?,
Cmd::Config(c) => c.run().await?,
Cmd::Txn(tx) => tx.run().await?,
Cmd::Cache(data) => data.run()?,
};
Ok(())
Expand Down Expand Up @@ -141,6 +143,9 @@ pub enum Cmd {
Network(network::Cmd),
/// Print version information
Version(version::Cmd),
/// Sign, Simulate, and Send transactions
#[command(subcommand)]
Txn(txn::Cmd),
/// Cache for tranasctions and contract specs
#[command(subcommand)]
Cache(cache::Cmd),
Expand All @@ -166,6 +171,8 @@ pub enum Error {
#[error(transparent)]
Network(#[from] network::Error),
#[error(transparent)]
Txn(#[from] txn::Error),
#[error(transparent)]
Cache(#[from] cache::Error),
}

Expand Down
48 changes: 48 additions & 0 deletions cmd/soroban-cli/src/commands/txn/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use clap::Parser;

pub mod send;
pub mod sign;
pub mod simulate;
pub mod xdr;

use stellar_xdr::cli as xdr_cli;

#[derive(Debug, Parser)]
pub enum Cmd {
/// Add a new identity (keypair, ledger, macOS keychain)
Inspect(xdr_cli::Root),
/// Given an identity return its address (public key)
Sign(sign::Cmd),
/// Submit a transaction to the network
Send(send::Cmd),
/// Simulate a transaction
Simulate(simulate::Cmd),
}

#[derive(thiserror::Error, Debug)]
pub enum Error {
/// An error during the simulation
#[error(transparent)]
Simulate(#[from] simulate::Error),
/// An error during the inspect
#[error(transparent)]
Inspect(#[from] xdr_cli::Error),
/// An error during the sign
#[error(transparent)]
Sign(#[from] sign::Error),
/// An error during the send
#[error(transparent)]
Send(#[from] send::Error),
}

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
match self {
Cmd::Inspect(cmd) => cmd.run()?,
Cmd::Sign(cmd) => cmd.run().await?,
Cmd::Send(cmd) => cmd.run().await?,
Cmd::Simulate(cmd) => cmd.run().await?,
};
Ok(())
}
}
19 changes: 19 additions & 0 deletions cmd/soroban-cli/src/commands/txn/send.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
XdrArgs(#[from] super::xdr::Error),
}

#[derive(Debug, clap::Parser, Clone)]
#[group(skip)]
pub struct Cmd {
#[clap(flatten)]
pub xdr_args: super::xdr::Args,
}

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
println!("{:#?}", self.xdr_args.txn()?);
Ok(())
}
}
19 changes: 19 additions & 0 deletions cmd/soroban-cli/src/commands/txn/sign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
XdrArgs(#[from] super::xdr::Error),
}

#[derive(Debug, clap::Parser, Clone)]
#[group(skip)]
pub struct Cmd {
#[clap(flatten)]
pub xdr_args: super::xdr::Args,
}

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
println!("{:#?}", self.xdr_args.txn()?);
Ok(())
}
}
19 changes: 19 additions & 0 deletions cmd/soroban-cli/src/commands/txn/simulate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
XdrArgs(#[from] super::xdr::Error),
}

#[derive(Debug, clap::Parser, Clone)]
#[group(skip)]
pub struct Cmd {
#[clap(flatten)]
pub xdr_args: super::xdr::Args,
}

impl Cmd {
pub async fn run(&self) -> Result<(), Error> {
println!("{:#?}", self.xdr_args.txn()?);
Ok(())
}
}
55 changes: 55 additions & 0 deletions cmd/soroban-cli/src/commands/txn/xdr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use std::{io::stdin, path::PathBuf};

use soroban_env_host::xdr::ReadXdr;
use soroban_sdk::xdr::{Limited, Limits, Transaction};

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("failed to decode XDR from base64")]
Base64Decode,
#[error("failed to decode XDR from file: {0}")]
FileDecode(PathBuf),
#[error("failed to decode XDR from stdin")]
StdinDecode,
#[error(transparent)]
Io(#[from] std::io::Error),
}

/// XDR input, either base64 encoded or file path and stdin if neither is provided
#[derive(Debug, clap::Args, Clone)]
#[group(skip)]
pub struct Args {
/// Base64 encoded XDR transaction
#[arg(
long = "xdr-base64",
env = "STELLAR_TXN_XDR_BASE64",
conflicts_with = "xdr_file"
)]
pub xdr_base64: Option<String>,
//// File containing Binary encoded data
#[arg(
long = "xdr-file",
env = "STELLAR_TXN_XDR_FILE",
conflicts_with = "xdr_base64"
)]
pub xdr_file: Option<PathBuf>,
}

impl Args {
pub fn xdr<T: ReadXdr>(&self) -> Result<T, Error> {
match (self.xdr_base64.as_ref(), self.xdr_file.as_ref()) {
(Some(xdr_base64), None) => {
T::from_xdr_base64(xdr_base64, Limits::none()).map_err(|_| Error::Base64Decode)
}
(_, Some(xdr_file)) => T::from_xdr(std::fs::read(xdr_file)?, Limits::none())
.map_err(|_| Error::FileDecode(xdr_file.clone())),

_ => T::read_xdr_base64_to_end(&mut Limited::new(stdin(), Limits::none()))
.map_err(|_| Error::StdinDecode),
}
}

pub fn txn(&self) -> Result<Transaction, Error> {
self.xdr::<Transaction>()
}
}

0 comments on commit 0443ef2

Please sign in to comment.