Skip to content

Commit

Permalink
feat: tx send (#1592)
Browse files Browse the repository at this point in the history
Co-authored-by: Leigh McCulloch <[email protected]>
  • Loading branch information
willemneal and leighmcculloch authored Sep 24, 2024
1 parent ff57159 commit ce31909
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 8 deletions.
17 changes: 17 additions & 0 deletions FULL_HELP_DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,7 @@ Sign, Simulate, and Send transactions
* `simulate` — Simulate a transaction envelope from stdin
* `hash` — Calculate the hash of a transaction envelope from stdin
* `sign` — Sign a transaction envelope appending the signature to the envelope
* `send` — Send a transaction envelope to the network



Expand Down Expand Up @@ -1345,6 +1346,22 @@ Sign a transaction envelope appending the signature to the envelope



## `stellar tx send`

Send a transaction envelope to the network

**Usage:** `stellar tx send [OPTIONS]`

###### **Options:**

* `--rpc-url <RPC_URL>` — RPC server endpoint
* `--network-passphrase <NETWORK_PASSPHRASE>` — Network passphrase to sign the transaction sent to the rpc server
* `--network <NETWORK>` — Name of network to use from config
* `--global` — Use global config
* `--config-dir <CONFIG_DIR>` — Location of config directory, default is "."



## `stellar xdr`

Decode and encode XDR
Expand Down
16 changes: 10 additions & 6 deletions cmd/crates/soroban-test/tests/it/integration/tx.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use soroban_rpc::GetTransactionResponse;
use soroban_sdk::xdr::{Limits, ReadXdr, TransactionEnvelope, WriteXdr};
use soroban_test::{AssertExt, TestEnv};

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

#[tokio::test]
async fn simulate() {
Expand Down Expand Up @@ -73,9 +74,12 @@ async fn build_simulate_sign_send() {
.stdout_as_str();
dbg!("{tx_signed}");

// 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();
let rpc_result = client.send_transaction_polling(&tx_signed).await.unwrap();
assert_eq!(rpc_result.status, "SUCCESS");
let output = sandbox
.new_assert_cmd("tx")
.arg("send")
.write_stdin(tx_signed.as_bytes())
.assert()
.success()
.stdout_as_str();
assert_eq!(output, "SUCCESS");
}
8 changes: 6 additions & 2 deletions cmd/soroban-cli/src/commands/tx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use clap::Parser;
use super::global;

pub mod hash;
pub mod send;
pub mod sign;
pub mod simulate;
pub mod xdr;
Expand All @@ -15,18 +16,20 @@ pub enum Cmd {
Hash(hash::Cmd),
/// Sign a transaction envelope appending the signature to the envelope
Sign(sign::Cmd),
/// Send a transaction envelope to the network
Send(send::Cmd),
}

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

impl Cmd {
Expand All @@ -35,6 +38,7 @@ impl Cmd {
Cmd::Simulate(cmd) => cmd.run(global_args).await?,
Cmd::Hash(cmd) => cmd.run(global_args)?,
Cmd::Sign(cmd) => cmd.run(global_args).await?,
Cmd::Send(cmd) => cmd.run(global_args).await?,
};
Ok(())
}
Expand Down
59 changes: 59 additions & 0 deletions cmd/soroban-cli/src/commands/tx/send.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use async_trait::async_trait;
use soroban_rpc::GetTransactionResponse;

use crate::commands::{global, NetworkRunnable};
use crate::config::{self, locator, network};

#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error(transparent)]
XdrArgs(#[from] super::xdr::Error),
#[error(transparent)]
Network(#[from] network::Error),
#[error(transparent)]
Config(#[from] config::Error),
#[error(transparent)]
Rpc(#[from] crate::rpc::Error),
#[error(transparent)]
SerdeJson(#[from] serde_json::Error),
}

#[derive(Debug, clap::Parser, Clone)]
#[group(skip)]
/// Command to send a transaction envelope to the network
/// e.g. `cat file.txt | soroban tx send`
pub struct Cmd {
#[clap(flatten)]
pub network: network::Args,
#[clap(flatten)]
pub locator: locator::Args,
}

impl Cmd {
pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
let response = self.run_against_rpc_server(Some(global_args), None).await?;
println!("{}", serde_json::to_string_pretty(&response)?);
Ok(())
}
}

#[async_trait]
impl NetworkRunnable for Cmd {
type Error = Error;

type Result = GetTransactionResponse;
async fn run_against_rpc_server(
&self,
_: Option<&global::Args>,
config: Option<&config::Args>,
) -> Result<Self::Result, Self::Error> {
let network = if let Some(config) = config {
config.get_network()?
} else {
self.network.get(&self.locator)?
};
let client = crate::rpc::Client::new(&network.rpc_url)?;
let tx_env = super::xdr::tx_envelope_from_stdin()?;
Ok(client.send_transaction_polling(&tx_env).await?)
}
}

0 comments on commit ce31909

Please sign in to comment.