Skip to main content

soroban_cli/commands/tx/
send.rs

1use crate::print::Print;
2use soroban_rpc::GetTransactionResponse;
3use std::ffi::OsString;
4
5use crate::{
6    commands::global,
7    config::{self, locator, network},
8};
9
10#[derive(thiserror::Error, Debug)]
11pub enum Error {
12    #[error(transparent)]
13    XdrArgs(#[from] super::xdr::Error),
14    #[error(transparent)]
15    Network(#[from] network::Error),
16    #[error(transparent)]
17    Config(#[from] config::Error),
18    #[error(transparent)]
19    Rpc(#[from] crate::rpc::Error),
20    #[error(transparent)]
21    SerdeJson(#[from] serde_json::Error),
22    #[error("xdr processing error: {0}")]
23    Xdr(#[from] stellar_xdr::Error),
24}
25
26#[derive(Debug, clap::Parser, Clone)]
27#[group(skip)]
28/// Command to send a transaction envelope to the network
29/// e.g. `stellar tx send file.txt` or `cat file.txt | stellar tx send`
30pub struct Cmd {
31    /// Base-64 transaction envelope XDR or file containing XDR to decode, or stdin if empty
32    #[arg()]
33    pub tx_xdr: Option<OsString>,
34    #[clap(flatten)]
35    pub network: network::Args,
36    #[clap(flatten)]
37    pub locator: locator::Args,
38}
39
40impl Cmd {
41    pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
42        let response = self
43            .execute(
44                &config::Args {
45                    locator: self.locator.clone(),
46                    network: self.network.clone(),
47                    source_account: config::UnresolvedMuxedAccount::default(),
48                    sign_with: config::sign_with::Args::default(),
49                    fee: None,
50                    inclusion_fee: None,
51                },
52                global_args.quiet,
53            )
54            .await?;
55        println!("{}", serde_json::to_string_pretty(&response)?);
56        Ok(())
57    }
58
59    pub async fn execute(
60        &self,
61        config: &config::Args,
62        quiet: bool,
63    ) -> Result<GetTransactionResponse, Error> {
64        let network = config.get_network()?;
65        let client = network.rpc_client()?;
66        let tx_env = super::xdr::tx_envelope_from_input(&self.tx_xdr)?;
67
68        if let Ok(txn) = super::xdr::unwrap_envelope_v1(tx_env.clone()) {
69            let print = Print::new(quiet);
70            print.log_transaction(&txn, &network, true)?;
71        }
72
73        Ok(client.send_transaction_polling(&tx_env).await?)
74    }
75}