soroban_sdk/
lib.rs

1//! Soroban SDK supports writing smart contracts for the Wasm-powered [Soroban] smart contract
2//! runtime, deployed on [Stellar].
3//!
4//! ### Docs
5//!
6//! See [developers.stellar.org] for documentation about building smart contracts for [Stellar].
7//!
8//! [developers.stellar.org]: https://developers.stellar.org
9//! [Stellar]: https://stellar.org
10//! [Soroban]: https://stellar.org/soroban
11//!
12//! ### Migrating Major Versions
13//!
14//! See [_migrating] for a summary of how to migrate from one major version to another.
15//!
16//! ### Examples
17//!
18//! ```rust
19//! use soroban_sdk::{contract, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
20//!
21//! #[contract]
22//! pub struct Contract;
23//!
24//! #[contractimpl]
25//! impl Contract {
26//!     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
27//!         vec![&env, symbol_short!("Hello"), to]
28//!     }
29//! }
30//!
31//! #[test]
32//! fn test() {
33//! # }
34//! # #[cfg(feature = "testutils")]
35//! # fn main() {
36//!     let env = Env::default();
37//!     let contract_id = env.register(Contract, ());
38//!     let client = ContractClient::new(&env, &contract_id);
39//!
40//!     let words = client.hello(&symbol_short!("Dev"));
41//!
42//!     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
43//! }
44//! # #[cfg(not(feature = "testutils"))]
45//! # fn main() { }
46//! ```
47//!
48//! More examples are available at:
49//! - <https://developers.stellar.org/docs/build/smart-contracts/example-contracts>
50//! - <https://developers.stellar.org/docs/build/guides>
51
52#![cfg_attr(target_family = "wasm", no_std)]
53#![cfg_attr(feature = "docs", feature(doc_cfg))]
54#![allow(dead_code)]
55
56pub mod _migrating;
57
58#[cfg(all(target_family = "wasm", feature = "testutils"))]
59compile_error!("'testutils' feature is not supported on 'wasm' target");
60
61// When used in a no_std contract, provide a panic handler as one is required.
62#[cfg(target_family = "wasm")]
63#[panic_handler]
64fn handle_panic(_: &core::panic::PanicInfo) -> ! {
65    core::arch::wasm32::unreachable()
66}
67
68// Here we provide a `#[global_allocator]` that is a minimal non-freeing bump
69// allocator, appropriate for a WASM blob that runs a single contract call.
70#[cfg(all(feature = "alloc", target_family = "wasm"))]
71mod alloc;
72
73/// This const block contains link sections that need to end up in the final
74/// build of any contract using the SDK.
75///
76/// In Rust's build system sections only get included into the final build if
77/// the object file containing those sections are processed by the linker, but
78/// as an optimization step if no code is called in an object file it is
79/// discarded.  This has the unfortunate effect of causing anything else in
80/// those object files, such as link sections, to be discarded. Placing anything
81/// that must be included in the build inside an exported static or function
82/// ensures the object files won't be discarded. wasm-bindgen does a similar
83/// thing to this with a function, and so this seems to be a reasonably
84/// accepted way to work around this limitation in the build system. The SDK
85/// uses a static exported with name `_` that becomes a global because a global
86/// is more unnoticeable, and takes up less bytes.
87///
88/// The const block has no affect on the above problem and exists only to group
89/// the static and link sections under a shared cfg.
90///
91/// See https://github.com/stellar/rs-soroban-sdk/issues/383 for more details.
92#[cfg(target_family = "wasm")]
93const _: () = {
94    /// This exported static is guaranteed to end up in the final binary of any
95    /// importer, as a global. It exists to ensure the link sections are
96    /// included in the final build artifact. See notes above.
97    #[export_name = "_"]
98    static __: () = ();
99
100    #[link_section = "contractenvmetav0"]
101    static __ENV_META_XDR: [u8; env::internal::meta::XDR.len()] = env::internal::meta::XDR;
102
103    // Rustc version.
104    contractmeta!(key = "rsver", val = env!("RUSTC_VERSION"),);
105
106    // Rust Soroban SDK version.
107    contractmeta!(
108        key = "rssdkver",
109        val = concat!(env!("CARGO_PKG_VERSION"), "#", env!("GIT_REVISION")),
110    );
111};
112
113// Re-exports of dependencies used by macros.
114#[doc(hidden)]
115pub mod reexports_for_macros {
116    pub use ::bytes_lit;
117    #[cfg(any(test, feature = "testutils"))]
118    pub use ::ctor;
119}
120
121/// Assert in contract asserts that the contract is currently executing within a
122/// contract. The macro maps to code when testutils are enabled or in tests,
123/// otherwise maps to nothing.
124#[macro_export]
125macro_rules! assert_in_contract {
126    ($env:expr $(,)?) => {{
127        {
128            #[cfg(any(test, feature = "testutils"))]
129            assert!(
130                ($env).in_contract(),
131                "this function is not accessible outside of a contract, wrap \
132                the call with `env.as_contract()` to access it from a \
133                particular contract"
134            );
135        }
136    }};
137}
138
139/// Create a short [Symbol] constant with the given string.
140///
141/// A short symbol's maximum length is 9 characters. For longer symbols, use
142/// [Symbol::new] to create the symbol at runtime.
143///
144/// Valid characters are `a-zA-Z0-9_`.
145///
146/// The [Symbol] is generated at compile time and returned as a const.
147///
148/// ### Examples
149///
150/// ```
151/// use soroban_sdk::{symbol_short, Symbol};
152///
153/// let symbol = symbol_short!("a_str");
154/// assert_eq!(symbol, symbol_short!("a_str"));
155/// ```
156pub use soroban_sdk_macros::symbol_short;
157
158/// Generates conversions from the repr(u32) enum from/into an `Error`.
159///
160/// There are some constraints on the types that are supported:
161/// - Enum must derive `Copy`.
162/// - Enum variants must have an explicit integer literal.
163/// - Enum variants must have a value convertible to u32.
164///
165/// Includes the type in the contract spec so that clients can generate bindings
166/// for the type.
167///
168/// ### Examples
169///
170/// Defining an error and capturing errors using the `try_` variant.
171///
172/// ```
173/// use soroban_sdk::{contract, contracterror, contractimpl, Env};
174///
175/// #[contracterror]
176/// #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
177/// #[repr(u32)]
178/// pub enum Error {
179///     MyError = 1,
180///     AnotherError = 2,
181/// }
182///
183/// #[contract]
184/// pub struct Contract;
185///
186/// #[contractimpl]
187/// impl Contract {
188///     pub fn causeerror(env: Env) -> Result<(), Error> {
189///         Err(Error::MyError)
190///     }
191/// }
192///
193/// #[test]
194/// fn test() {
195/// # }
196/// # #[cfg(feature = "testutils")]
197/// # fn main() {
198///     let env = Env::default();
199///
200///     // Register the contract defined in this crate.
201///     let contract_id = env.register(Contract, ());
202///
203///     // Create a client for calling the contract.
204///     let client = ContractClient::new(&env, &contract_id);
205///
206///     // Invoke contract causeerror function, but use the try_ variant that
207///     // will capture the error so we can inspect.
208///     let result = client.try_causeerror();
209///     assert_eq!(result, Err(Ok(Error::MyError)));
210/// }
211/// # #[cfg(not(feature = "testutils"))]
212/// # fn main() { }
213/// ```
214///
215/// Testing invocations that cause errors with `should_panic` instead of `try_`.
216///
217/// ```should_panic
218/// # use soroban_sdk::{contract, contracterror, contractimpl, Env};
219/// #
220/// # #[contracterror]
221/// # #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
222/// # #[repr(u32)]
223/// # pub enum Error {
224/// #     MyError = 1,
225/// #     AnotherError = 2,
226/// # }
227/// #
228/// # #[contract]
229/// # pub struct Contract;
230/// #
231/// # #[contractimpl]
232/// # impl Contract {
233/// #     pub fn causeerror(env: Env) -> Result<(), Error> {
234/// #         Err(Error::MyError)
235/// #     }
236/// # }
237/// #
238/// #[test]
239/// #[should_panic(expected = "ContractError(1)")]
240/// fn test() {
241/// # panic!("ContractError(1)");
242/// # }
243/// # #[cfg(feature = "testutils")]
244/// # fn main() {
245///     let env = Env::default();
246///
247///     // Register the contract defined in this crate.
248///     let contract_id = env.register(Contract, ());
249///
250///     // Create a client for calling the contract.
251///     let client = ContractClient::new(&env, &contract_id);
252///
253///     // Invoke contract causeerror function.
254///     client.causeerror();
255/// }
256/// # #[cfg(not(feature = "testutils"))]
257/// # fn main() { }
258/// ```
259pub use soroban_sdk_macros::contracterror;
260
261/// Import a contract from its WASM file, generating a client, types, and
262/// constant holding the contract file.
263///
264/// The path given is relative to the workspace root, and not the current
265/// file.
266///
267/// Generates in the current module:
268/// - A `Contract` trait that matches the contracts interface.
269/// - A `ContractClient` struct that has functions for each function in the
270/// contract.
271/// - Types for all contract types defined in the contract.
272///
273/// ### Examples
274///
275/// ```ignore
276/// use soroban_sdk::{contractimpl, BytesN, Env, Symbol};
277///
278/// mod contract_a {
279///     soroban_sdk::contractimport!(file = "contract_a.wasm");
280/// }
281///
282/// pub struct ContractB;
283///
284/// #[contractimpl]
285/// impl ContractB {
286///     pub fn add_with(env: Env, contract_id: BytesN<32>, x: u32, y: u32) -> u32 {
287///         let client = contract_a::ContractClient::new(&env, contract_id);
288///         client.add(&x, &y)
289///     }
290/// }
291///
292/// #[test]
293/// fn test() {
294///     let env = Env::default();
295///
296///     // Register contract A using the imported WASM.
297///     let contract_a_id = env.register_contract_wasm(None, contract_a::WASM);
298///
299///     // Register contract B defined in this crate.
300///     let contract_b_id = env.register(ContractB, ());
301///
302///     // Create a client for calling contract B.
303///     let client = ContractBClient::new(&env, &contract_b_id);
304///
305///     // Invoke contract B via its client.
306///     let sum = client.add_with(&contract_a_id, &5, &7);
307///     assert_eq!(sum, 12);
308/// }
309/// ```
310pub use soroban_sdk_macros::contractimport;
311
312/// Marks a type as being the type that contract functions are attached for.
313///
314/// Use `#[contractimpl]` on impl blocks of this type to make those functions
315/// contract functions.
316///
317/// Note that a crate only ever exports a single contract. While there can be
318/// multiple types in a crate with `#[contract]`, when built as a wasm file and
319/// deployed the combination of all contract functions and all contracts within
320/// a crate will be seen as a single contract.
321///
322/// ### Examples
323///
324/// Define a contract with one function, `hello`, and call it from within a test
325/// using the generated client.
326///
327/// ```
328/// use soroban_sdk::{contract, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
329///
330/// #[contract]
331/// pub struct HelloContract;
332///
333/// #[contractimpl]
334/// impl HelloContract {
335///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
336///         vec![&env, symbol_short!("Hello"), to]
337///     }
338/// }
339///
340/// #[test]
341/// fn test() {
342/// # }
343/// # #[cfg(feature = "testutils")]
344/// # fn main() {
345///     let env = Env::default();
346///     let contract_id = env.register(HelloContract, ());
347///     let client = HelloContractClient::new(&env, &contract_id);
348///
349///     let words = client.hello(&symbol_short!("Dev"));
350///
351///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
352/// }
353/// # #[cfg(not(feature = "testutils"))]
354/// # fn main() { }
355/// ```
356pub use soroban_sdk_macros::contract;
357
358/// Exports the publicly accessible functions to the Soroban environment.
359///
360/// Functions that are publicly accessible in the implementation are invocable
361/// by other contracts, or directly by transactions, when deployed.
362///
363/// ### Examples
364///
365/// Define a contract with one function, `hello`, and call it from within a test
366/// using the generated client.
367///
368/// ```
369/// use soroban_sdk::{contract, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
370///
371/// #[contract]
372/// pub struct HelloContract;
373///
374/// #[contractimpl]
375/// impl HelloContract {
376///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
377///         vec![&env, symbol_short!("Hello"), to]
378///     }
379/// }
380///
381/// #[test]
382/// fn test() {
383/// # }
384/// # #[cfg(feature = "testutils")]
385/// # fn main() {
386///     let env = Env::default();
387///     let contract_id = env.register(HelloContract, ());
388///     let client = HelloContractClient::new(&env, &contract_id);
389///
390///     let words = client.hello(&symbol_short!("Dev"));
391///
392///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
393/// }
394/// # #[cfg(not(feature = "testutils"))]
395/// # fn main() { }
396/// ```
397pub use soroban_sdk_macros::contractimpl;
398
399/// Adds a serialized SCMetaEntry::SCMetaV0 to the WASM contracts custom section
400/// under the section name 'contractmetav0'. Contract developers can use this to
401/// append metadata to their contract.
402///
403/// ### Examples
404///
405/// ```
406/// use soroban_sdk::{contract, contractimpl, contractmeta, vec, symbol_short, BytesN, Env, Symbol, Vec};
407///
408/// contractmeta!(key="desc", val="hello world contract");
409///
410/// #[contract]
411/// pub struct HelloContract;
412///
413/// #[contractimpl]
414/// impl HelloContract {
415///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
416///         vec![&env, symbol_short!("Hello"), to]
417///     }
418/// }
419///
420///
421/// #[test]
422/// fn test() {
423/// # }
424/// # #[cfg(feature = "testutils")]
425/// # fn main() {
426///     let env = Env::default();
427///     let contract_id = env.register(HelloContract, ());
428///     let client = HelloContractClient::new(&env, &contract_id);
429///
430///     let words = client.hello(&symbol_short!("Dev"));
431///
432///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
433/// }
434/// # #[cfg(not(feature = "testutils"))]
435/// # fn main() { }
436/// ```
437pub use soroban_sdk_macros::contractmeta;
438
439/// Generates conversions from the struct/enum from/into a `Val`.
440///
441/// There are some constraints on the types that are supported:
442/// - Enums with integer values must have an explicit integer literal for every
443/// variant.
444/// - Enums with unit variants are supported.
445/// - Enums with tuple-like variants with a maximum of one tuple field are
446/// supported. The tuple field must be of a type that is also convertible to and
447/// from `Val`.
448/// - Enums with struct-like variants are not supported.
449/// - Structs are supported. All fields must be of a type that is also
450/// convertible to and from `Val`.
451/// - All variant names, field names, and type names must be 10-characters or
452/// less in length.
453///
454/// Includes the type in the contract spec so that clients can generate bindings
455/// for the type.
456///
457/// ### Examples
458///
459/// Defining a contract type that is a struct and use it in a contract.
460///
461/// ```
462/// #![no_std]
463/// use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Env, Symbol};
464///
465/// #[contracttype]
466/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
467/// pub struct State {
468///     pub count: u32,
469///     pub last_incr: u32,
470/// }
471///
472/// #[contract]
473/// pub struct Contract;
474///
475/// #[contractimpl]
476/// impl Contract {
477///     /// Increment increments an internal counter, and returns the value.
478///     pub fn increment(env: Env, incr: u32) -> u32 {
479///         // Get the current count.
480///         let mut state = Self::get_state(env.clone());
481///
482///         // Increment the count.
483///         state.count += incr;
484///         state.last_incr = incr;
485///
486///         // Save the count.
487///         env.storage().persistent().set(&symbol_short!("STATE"), &state);
488///
489///         // Return the count to the caller.
490///         state.count
491///     }
492///
493///     /// Return the current state.
494///     pub fn get_state(env: Env) -> State {
495///         env.storage().persistent()
496///             .get(&symbol_short!("STATE"))
497///             .unwrap_or_else(|| State::default()) // If no value set, assume 0.
498///     }
499/// }
500///
501/// #[test]
502/// fn test() {
503/// # }
504/// # #[cfg(feature = "testutils")]
505/// # fn main() {
506///     let env = Env::default();
507///     let contract_id = env.register(Contract, ());
508///     let client = ContractClient::new(&env, &contract_id);
509///
510///     assert_eq!(client.increment(&1), 1);
511///     assert_eq!(client.increment(&10), 11);
512///     assert_eq!(
513///         client.get_state(),
514///         State {
515///             count: 11,
516///             last_incr: 10,
517///         },
518///     );
519/// }
520/// # #[cfg(not(feature = "testutils"))]
521/// # fn main() { }
522/// ```
523///
524/// Defining contract types that are three different types of enums and using
525/// them in a contract.
526///
527/// ```
528/// #![no_std]
529/// use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Symbol, Env};
530///
531/// /// A tuple enum is stored as a two-element vector containing the name of
532/// /// the enum variant as a Symbol, then the value in the tuple.
533/// #[contracttype]
534/// #[derive(Clone, Debug, Eq, PartialEq)]
535/// pub enum Color {
536///     Red(Intensity),
537///     Blue(Shade),
538/// }
539///
540/// /// A unit enum is stored as a single-element vector containing the name of
541/// /// the enum variant as a Symbol.
542/// #[contracttype]
543/// #[derive(Clone, Debug, Eq, PartialEq)]
544/// pub enum Shade {
545///     Light,
546///     Dark,
547/// }
548///
549/// /// An integer enum is stored as its integer value.
550/// #[contracttype]
551/// #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
552/// #[repr(u32)]
553/// pub enum Intensity {
554///     Low = 1,
555///     High = 2,
556/// }
557///
558/// #[contract]
559/// pub struct Contract;
560///
561/// #[contractimpl]
562/// impl Contract {
563///     /// Set the color.
564///     pub fn set(env: Env, c: Color) {
565///         env.storage().persistent().set(&symbol_short!("COLOR"), &c);
566///     }
567///
568///     /// Get the color.
569///     pub fn get(env: Env) -> Option<Color> {
570///         env.storage().persistent()
571///             .get(&symbol_short!("COLOR"))
572///     }
573/// }
574///
575/// #[test]
576/// fn test() {
577/// # }
578/// # #[cfg(feature = "testutils")]
579/// # fn main() {
580///     let env = Env::default();
581///     let contract_id = env.register(Contract, ());
582///     let client = ContractClient::new(&env, &contract_id);
583///
584///     assert_eq!(client.get(), None);
585///
586///     client.set(&Color::Red(Intensity::High));
587///     assert_eq!(client.get(), Some(Color::Red(Intensity::High)));
588///
589///     client.set(&Color::Blue(Shade::Light));
590///     assert_eq!(client.get(), Some(Color::Blue(Shade::Light)));
591/// }
592/// # #[cfg(not(feature = "testutils"))]
593/// # fn main() { }
594/// ```
595pub use soroban_sdk_macros::contracttype;
596
597/// Generates conversions from the struct into a published event.
598///
599/// Fields of the struct become topics and data parameters in the published event.
600///
601/// Includes the event in the contract spec so that clients can generate bindings
602/// for the type and downstream systems can understand the meaning of the event.
603///
604/// ### Examples
605///
606/// #### Define an Event
607///
608/// The event will have a single fixed topic matching the name of the struct in lower snake
609/// case. The fixed topic will appear before any topics listed as fields. In the example
610/// below, the topics for the event will be:
611/// - `"my_event"`
612/// - u32 value from the `my_topic` field
613///
614/// The event's data will be a [`Map`], containing a key-value pair for each field with the key
615/// being the name as a [`Symbol`]. In the example below, the data for the event will be:
616/// - key: my_event_data => val: u32
617/// - key: more_event_data => val: u64
618///
619/// ```
620/// #![no_std]
621/// use soroban_sdk::contractevent;
622///
623/// // Define the event using the `contractevent` attribute macro.
624/// #[contractevent]
625/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
626/// pub struct MyEvent {
627///     // Mark fields as topics, for the value to be included in the events topic list so
628///     // that downstream systems know to index it.
629///     #[topic]
630///     pub my_topic: u32,
631///     // Fields not marked as topics will appear in the events data section.
632///     pub my_event_data: u32,
633///     pub more_event_data: u64,
634/// }
635///
636/// # fn main() { }
637/// ```
638///
639/// #### Define an Event with Custom Topics
640///
641/// Define a contract event with a custom list of fixed topics.
642///
643/// The fixed topics can be change to another value. In the example
644/// below, the topics for the event will be:
645/// - `"my_contract"`
646/// - `"an_event"`
647/// - u32 value from the `my_topic` field
648///
649/// ```
650/// #![no_std]
651/// use soroban_sdk::contractevent;
652///
653/// // Define the event using the `contractevent` attribute macro.
654/// #[contractevent(topics = ["my_contract", "an_event"])]
655/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
656/// pub struct MyEvent {
657///     // Mark fields as topics, for the value to be included in the events topic list so
658///     // that downstream systems know to index it.
659///     #[topic]
660///     pub my_topic: u32,
661///     // Fields not marked as topics will appear in the events data section.
662///     pub my_event_data: u32,
663///     pub more_event_data: u64,
664/// }
665///
666/// # fn main() { }
667/// ```
668///
669/// #### Define an Event with Other Data Formats
670///
671/// The data format of the event is a map by default, but can alternatively be defined as a `vec`
672/// or `single-value`.
673///
674/// ##### Vec
675///
676/// In the example below, the data for the event will be a [`Vec`] containing:
677/// - u32
678/// - u64
679///
680/// ```
681/// #![no_std]
682/// use soroban_sdk::contractevent;
683///
684/// // Define the event using the `contractevent` attribute macro.
685/// #[contractevent(data_format = "vec")]
686/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
687/// pub struct MyEvent {
688///     // Mark fields as topics, for the value to be included in the events topic list so
689///     // that downstream systems know to index it.
690///     #[topic]
691///     pub my_topic: u32,
692///     // Fields not marked as topics will appear in the events data section.
693///     pub my_event_data: u32,
694///     pub more_event_data: u64,
695/// }
696///
697/// # fn main() { }
698/// ```
699///
700/// ##### Single Value
701///
702/// In the example below, the data for the event will be a u32.
703///
704/// When the data format is a single value there must be no more than one data field.
705///
706/// ```
707/// #![no_std]
708/// use soroban_sdk::contractevent;
709///
710/// // Define the event using the `contractevent` attribute macro.
711/// #[contractevent(data_format = "single-value")]
712/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
713/// pub struct MyEvent {
714///     // Mark fields as topics, for the value to be included in the events topic list so
715///     // that downstream systems know to index it.
716///     #[topic]
717///     pub my_topic: u32,
718///     // Fields not marked as topics will appear in the events data section.
719///     pub my_event_data: u32,
720/// }
721///
722/// # fn main() { }
723/// ```
724///
725/// #### A Full Example
726///
727/// Defining an event, publishing it in a contract, and testing it.
728///
729/// ```
730/// #![no_std]
731/// use soroban_sdk::{contract, contractevent, contractimpl, contracttype, symbol_short, Env, Symbol};
732///
733/// // Define the event using the `contractevent` attribute macro.
734/// #[contractevent]
735/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
736/// pub struct Increment {
737///     // Mark fields as topics, for the value to be included in the events topic list so
738///     // that downstream systems know to index it.
739///     #[topic]
740///     pub change: u32,
741///     // Fields not marked as topics will appear in the events data section.
742///     pub count: u32,
743/// }
744///
745/// #[contracttype]
746/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
747/// pub struct State {
748///     pub count: u32,
749///     pub last_incr: u32,
750/// }
751///
752/// #[contract]
753/// pub struct Contract;
754///
755/// #[contractimpl]
756/// impl Contract {
757///     /// Increment increments an internal counter, and returns the value.
758///     /// Publishes an event about the change in the counter.
759///     pub fn increment(env: Env, incr: u32) -> u32 {
760///         // Get the current count.
761///         let mut state = Self::get_state(env.clone());
762///
763///         // Increment the count.
764///         state.count += incr;
765///         state.last_incr = incr;
766///
767///         // Save the count.
768///         env.storage().persistent().set(&symbol_short!("STATE"), &state);
769///
770///         // Publish an event about the change.
771///         Increment {
772///             change: incr,
773///             count: state.count,
774///         }.publish(&env);
775///
776///         // Return the count to the caller.
777///         state.count
778///     }
779///
780///     /// Return the current state.
781///     pub fn get_state(env: Env) -> State {
782///         env.storage().persistent()
783///             .get(&symbol_short!("STATE"))
784///             .unwrap_or_else(|| State::default()) // If no value set, assume 0.
785///     }
786/// }
787///
788/// #[test]
789/// fn test() {
790/// # }
791/// # #[cfg(feature = "testutils")]
792/// # fn main() {
793///     let env = Env::default();
794///     let contract_id = env.register(Contract, ());
795///     let client = ContractClient::new(&env, &contract_id);
796///
797///     assert_eq!(client.increment(&1), 1);
798///     assert_eq!(client.increment(&10), 11);
799///     assert_eq!(
800///         client.get_state(),
801///         State {
802///             count: 11,
803///             last_incr: 10,
804///         },
805///     );
806/// }
807/// # #[cfg(not(feature = "testutils"))]
808/// # fn main() { }
809/// ```
810pub use soroban_sdk_macros::contractevent;
811
812/// Generates a type that helps build function args for a contract trait.
813pub use soroban_sdk_macros::contractargs;
814
815/// Generates a client for a contract trait.
816///
817/// Can be used to create clients for contracts that live outside the current
818/// crate, using a trait that has been published as a standard or shared
819/// interface.
820///
821/// Primarily useful when needing to generate a client for someone elses
822/// contract where they have only shared a trait interface.
823///
824/// Note that [`contractimpl`] also automatically generates a client, and so it
825/// is unnecessary to use [`contractclient`] for contracts that live in the
826/// current crate.
827///
828/// Note that [`contractimport`] also automatically generates a client when
829/// importing someone elses contract where they have shared a .wasm file.
830///
831/// ### Examples
832///
833/// ```
834/// use soroban_sdk::{contract, contractclient, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
835///
836/// #[contractclient(name = "Client")]
837/// pub trait HelloInteface {
838///     fn hello(env: Env, to: Symbol) -> Vec<Symbol>;
839/// }
840///
841/// #[contract]
842/// pub struct HelloContract;
843///
844/// #[contractimpl]
845/// impl HelloContract {
846///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
847///         vec![&env, symbol_short!("Hello"), to]
848///     }
849/// }
850///
851/// #[test]
852/// fn test() {
853/// # }
854/// # #[cfg(feature = "testutils")]
855/// # fn main() {
856///     let env = Env::default();
857///
858///     // Register the hello contract.
859///     let contract_id = env.register(HelloContract, ());
860///
861///     // Create a client for the hello contract, that was constructed using
862///     // the trait.
863///     let client = Client::new(&env, &contract_id);
864///
865///     let words = client.hello(&symbol_short!("Dev"));
866///
867///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
868/// }
869/// # #[cfg(not(feature = "testutils"))]
870/// # fn main() { }
871pub use soroban_sdk_macros::contractclient;
872
873/// Generates a contract spec for a trait or impl.
874///
875/// Note that [`contractimpl`] also generates a contract spec and it is in most
876/// cases not necessary to use this macro.
877#[doc(hidden)]
878pub use soroban_sdk_macros::contractspecfn;
879
880/// Import a contract from its WASM file, generating a constant holding the
881/// contract file.
882///
883/// Note that [`contractimport`] also automatically imports the contract file
884/// into a constant, and so it is usually unnecessary to use [`contractfile`]
885/// directly, unless you specifically want to only load the contract file
886/// without generating a client for it.
887pub use soroban_sdk_macros::contractfile;
888
889/// Panic with the given error.
890///
891/// The first argument in the list must be a reference to an [Env].
892///
893/// The second argument is an error value. The error value will be given to any
894/// calling contract.
895///
896/// Equivalent to `panic!`, but with an error value instead of a string. The
897/// error value will be given to any calling contract.
898///
899/// See [`contracterror`] for how to define an error type.
900#[macro_export]
901macro_rules! panic_with_error {
902    ($env:expr, $error:expr) => {{
903        $env.panic_with_error($error);
904    }};
905}
906
907#[doc(hidden)]
908#[deprecated(note = "use panic_with_error!")]
909#[macro_export]
910macro_rules! panic_error {
911    ($env:expr, $error:expr) => {{
912        $crate::panic_with_error!($env, $error);
913    }};
914}
915
916/// An internal panic! variant that avoids including the string
917/// when building for wasm (since it's just pointless baggage).
918#[cfg(target_family = "wasm")]
919macro_rules! sdk_panic {
920    ($_msg:literal) => {
921        panic!()
922    };
923    () => {
924        panic!()
925    };
926}
927#[cfg(not(target_family = "wasm"))]
928macro_rules! sdk_panic {
929    ($msg:literal) => {
930        panic!($msg)
931    };
932    () => {
933        panic!()
934    };
935}
936
937/// Assert a condition and panic with the given error if it is false.
938///
939/// The first argument in the list must be a reference to an [Env].
940///
941/// The second argument is an expression that if resolves to `false` will cause
942/// a panic with the error in the third argument.
943///
944/// The third argument is an error value. The error value will be given to any
945/// calling contract.
946///
947/// Equivalent to `assert!`, but with an error value instead of a string. The
948/// error value will be given to any calling contract.
949///
950/// See [`contracterror`] for how to define an error type.
951#[macro_export]
952macro_rules! assert_with_error {
953    ($env:expr, $cond:expr, $error:expr) => {{
954        if !($cond) {
955            $crate::panic_with_error!($env, $error);
956        }
957    }};
958}
959
960#[doc(hidden)]
961pub mod unwrap;
962
963mod env;
964
965mod address;
966mod muxed_address;
967mod symbol;
968
969pub use env::{ConversionError, Env};
970
971/// Raw value of the Soroban smart contract platform that types can be converted
972/// to and from for storing, or passing between contracts.
973///
974pub use env::Val;
975
976/// Used to do conversions between values in the Soroban environment.
977pub use env::FromVal;
978/// Used to do conversions between values in the Soroban environment.
979pub use env::IntoVal;
980/// Used to do conversions between values in the Soroban environment.
981pub use env::TryFromVal;
982/// Used to do conversions between values in the Soroban environment.
983pub use env::TryIntoVal;
984
985// Used by generated code only.
986#[doc(hidden)]
987pub use env::EnvBase;
988#[doc(hidden)]
989pub use env::Error;
990#[doc(hidden)]
991pub use env::MapObject;
992#[doc(hidden)]
993pub use env::SymbolStr;
994#[doc(hidden)]
995pub use env::VecObject;
996
997mod try_from_val_for_contract_fn;
998#[doc(hidden)]
999#[allow(deprecated)]
1000pub use try_from_val_for_contract_fn::TryFromValForContractFn;
1001
1002#[doc(hidden)]
1003#[deprecated(note = "use storage")]
1004pub mod data {
1005    #[doc(hidden)]
1006    #[deprecated(note = "use storage::Storage")]
1007    pub use super::storage::Storage as Data;
1008}
1009pub mod auth;
1010mod bytes;
1011pub mod crypto;
1012pub mod deploy;
1013mod error;
1014pub use error::InvokeError;
1015pub mod events;
1016pub use events::{Event, Topics};
1017pub mod iter;
1018pub mod ledger;
1019pub mod logs;
1020mod map;
1021pub mod prng;
1022pub mod storage;
1023pub mod token;
1024mod vec;
1025pub use address::{Address, Executable};
1026pub use bytes::{Bytes, BytesN};
1027pub use map::Map;
1028pub use muxed_address::MuxedAddress;
1029pub use symbol::Symbol;
1030pub use vec::Vec;
1031mod num;
1032pub use num::{Duration, Timepoint, I256, U256};
1033mod string;
1034pub use string::String;
1035mod tuple;
1036
1037mod constructor_args;
1038pub use constructor_args::ConstructorArgs;
1039
1040pub mod xdr;
1041
1042pub mod testutils;
1043
1044mod arbitrary_extra;
1045
1046mod tests;