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