Skip to main content

soroban_cli/commands/contract/
mod.rs

1pub mod alias;
2pub mod arg_parsing;
3pub mod asset;
4pub mod bindings;
5pub mod build;
6pub mod deploy;
7pub mod extend;
8pub mod fetch;
9pub mod id;
10pub mod info;
11pub mod init;
12pub mod inspect;
13pub mod invoke;
14pub mod optimize;
15pub mod read;
16pub mod restore;
17pub mod spec_verify;
18pub mod upload;
19
20use crate::{commands::global, print::Print, utils::deprecate_message};
21
22#[derive(Debug, clap::Subcommand)]
23pub enum Cmd {
24    /// Utilities to deploy a Stellar Asset Contract or get its id
25    #[command(subcommand)]
26    Asset(asset::Cmd),
27
28    /// Utilities to manage contract aliases
29    #[command(subcommand)]
30    Alias(alias::Cmd),
31
32    /// Generate code client bindings for a contract
33    #[command(subcommand)]
34    Bindings(bindings::Cmd),
35
36    Build(build::Cmd),
37
38    /// Extend the time to live ledger of a contract-data ledger entry.
39    ///
40    /// If no keys are specified the contract itself is extended.
41    Extend(extend::Cmd),
42
43    /// Deploy a wasm contract
44    Deploy(deploy::wasm::Cmd),
45
46    /// Fetch a contract's Wasm binary
47    Fetch(fetch::Cmd),
48
49    /// Generate the contract id for a given contract or asset
50    #[command(subcommand)]
51    Id(id::Cmd),
52
53    /// Access info about contracts
54    #[command(subcommand)]
55    Info(info::Cmd),
56
57    /// Initialize a Soroban contract project.
58    ///
59    /// This command will create a Cargo workspace project and add a sample Stellar contract.
60    /// The name of the contract can be specified by `--name`. It can be run multiple times
61    /// with different names in order to generate multiple contracts, and files won't
62    /// be overwritten unless `--overwrite` is passed.
63    Init(init::Cmd),
64
65    /// ⚠️ Deprecated, use `contract info`. Inspect a WASM file listing contract functions, meta, etc
66    #[command(display_order = 100)]
67    Inspect(inspect::Cmd),
68
69    /// Install a WASM file to the ledger without creating a contract instance
70    Upload(upload::Cmd),
71
72    /// ⚠️ Deprecated, use `contract upload`. Install a WASM file to the ledger without creating a contract instance
73    Install(upload::Cmd),
74
75    /// Invoke a contract function
76    ///
77    /// Generates an "implicit CLI" for the specified contract on-the-fly using the contract's
78    /// schema, which gets embedded into every Soroban contract. The "slop" in this command,
79    /// everything after the `--`, gets passed to this implicit CLI. Get in-depth help for a given
80    /// contract:
81    ///
82    ///     stellar contract invoke ... -- --help
83    Invoke(invoke::Cmd),
84
85    /// ⚠️ Deprecated, use `build --optimize`. Optimize a WASM file
86    Optimize(optimize::Cmd),
87
88    /// Print the current value of a contract-data ledger entry
89    Read(read::Cmd),
90
91    /// Restore an evicted value for a contract-data legder entry.
92    ///
93    /// If no keys are specificed the contract itself is restored.
94    Restore(restore::Cmd),
95
96    /// Verify that a contract spec references only defined types
97    // Hidden because it's unclear if this makes sense as a general subcommand
98    // to offer, but during the development of features relating to specs it has
99    // been helpful to have it as its own command. Verification is automatically
100    // run as part of `contract build` so for a general user this is not needed.
101    #[command(name = "spec-verify", hide = true)]
102    SpecVerify(spec_verify::Cmd),
103}
104
105#[derive(thiserror::Error, Debug)]
106pub enum Error {
107    #[error(transparent)]
108    Asset(#[from] asset::Error),
109
110    #[error(transparent)]
111    Alias(#[from] alias::Error),
112
113    #[error(transparent)]
114    Bindings(#[from] bindings::Error),
115
116    #[error(transparent)]
117    Build(#[from] build::Error),
118
119    #[error(transparent)]
120    Extend(#[from] extend::Error),
121
122    #[error(transparent)]
123    Deploy(#[from] deploy::wasm::Error),
124
125    #[error(transparent)]
126    Fetch(#[from] fetch::Error),
127
128    #[error(transparent)]
129    Init(#[from] init::Error),
130
131    #[error(transparent)]
132    Id(#[from] id::Error),
133
134    #[error(transparent)]
135    Info(#[from] info::Error),
136
137    #[error(transparent)]
138    Inspect(#[from] inspect::Error),
139
140    #[error(transparent)]
141    Install(#[from] upload::Error),
142
143    #[error(transparent)]
144    Invoke(#[from] invoke::Error),
145
146    #[error(transparent)]
147    Optimize(#[from] optimize::Error),
148
149    #[error(transparent)]
150    Read(#[from] read::Error),
151
152    #[error(transparent)]
153    Restore(#[from] restore::Error),
154
155    #[error(transparent)]
156    SpecVerify(#[from] spec_verify::Error),
157}
158
159impl Cmd {
160    pub async fn run(&self, global_args: &global::Args) -> Result<(), Error> {
161        let print = Print::new(global_args.quiet);
162
163        match &self {
164            Cmd::Asset(asset) => asset.run(global_args).await?,
165            Cmd::Bindings(bindings) => bindings.run().await?,
166            Cmd::Build(build) => {
167                build.run(global_args)?;
168            }
169            Cmd::Extend(extend) => extend.run(global_args).await?,
170            Cmd::Alias(alias) => alias.run(global_args)?,
171            Cmd::Deploy(deploy) => deploy.run(global_args).await?,
172            Cmd::Id(id) => id.run().await?,
173            Cmd::Info(info) => info.run(global_args).await?,
174            Cmd::Init(init) => init.run(global_args)?,
175            Cmd::Inspect(inspect) => {
176                deprecate_message(
177                    print,
178                    "stellar contract inspect",
179                    "Use `stellar contract info` instead.",
180                );
181                inspect.run()?;
182            }
183            Cmd::Install(install) => {
184                deprecate_message(
185                    print,
186                    "stellar contract install",
187                    "Use `stellar contract upload` instead.",
188                );
189                install.run(global_args).await?;
190            }
191            Cmd::Upload(upload) => upload.run(global_args).await?,
192            Cmd::Invoke(invoke) => invoke.run(global_args).await?,
193            Cmd::Optimize(optimize) => {
194                deprecate_message(
195                    print,
196                    "stellar contract optimize",
197                    "Use `stellar contract build --optimize` instead.",
198                );
199                optimize.run()?;
200            }
201            Cmd::Fetch(fetch) => fetch.run().await?,
202            Cmd::Read(read) => read.run().await?,
203            Cmd::Restore(restore) => restore.run(global_args).await?,
204            Cmd::SpecVerify(spec_verify) => spec_verify.run(global_args)?,
205        }
206        Ok(())
207    }
208}
209
210#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum)]
211pub enum Durability {
212    /// Persistent
213    Persistent,
214    /// Temporary
215    Temporary,
216}
217
218impl From<&Durability> for crate::xdr::ContractDataDurability {
219    fn from(d: &Durability) -> Self {
220        match d {
221            Durability::Persistent => crate::xdr::ContractDataDurability::Persistent,
222            Durability::Temporary => crate::xdr::ContractDataDurability::Temporary,
223        }
224    }
225}
226
227#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, clap::ValueEnum)]
228pub enum SpecOutput {
229    /// XDR of array of contract spec entries
230    XdrBase64,
231    /// Array of xdr of contract spec entries
232    XdrBase64Array,
233    /// Pretty print of contract spec entries
234    Docs,
235}