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