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(all(not(feature = "alloc"), target_family = "wasm"))]
63#[panic_handler]
64fn handle_panic(_: &core::panic::PanicInfo) -> ! {
65    core::arch::wasm32::unreachable()
66}
67
68// This is a bit subtle: we want to provide a narrowly-scoped feature `"alloc"`
69// that provides support for the `alloc` crate and its types, while using our
70// allocator (defined below in module `alloc`). We want to do this without
71// changing the user-interface a lot (in particular keeping users writing
72// `#[no_std]` and mostly not-using the stdlib casually, because it has many
73// components that produce large code footprint).
74//
75// This is _almost_ possible without involving `std` but unfortunately there's
76// still an allocation-error handler (`alloc_error_handler`) that there's no
77// stable way to install if one only uses the `alloc` crate, so we pull in a
78// dependency on `std` here (for now). When the stabilization of the allocation
79// error handler registration function happens in some future Rust version, or
80// it gets removed which it looks like work is heading towards instead, we can
81// remove std.
82//
83// See these issues for more details:
84// - https://github.com/rust-lang/rust/issues/51540
85// - https://github.com/rust-lang/rust/issues/66740
86// - https://github.com/rust-lang/rust/issues/66741
87#[cfg(all(feature = "alloc", target_family = "wasm"))]
88extern crate std;
89
90// Here we provide a `#[global_allocator]` that is a minimal non-freeing bump
91// allocator, appropriate for a WASM blob that runs a single contract call.
92#[cfg(all(feature = "alloc", target_family = "wasm"))]
93mod alloc;
94
95/// __link_sections returns and does nothing, but it contains link sections that
96/// should be ensured end up in the final build of any contract using the SDK.
97///
98/// In Rust's build system sections only get included into the final build if
99/// the object file containing those sections are processed by the linker, but
100/// as an optimization step if no code is called in an object file it is
101/// discarded.  This has the unfortunate effect of causing anything else in
102/// those object files, such as link sections, to be discarded. Placing anything
103/// that must be included in the build inside an exported function ensures the
104/// object files won't be discarded. wasm-bindgen does a similar thing to this,
105/// and so this seems to be a reasonably accepted way to work around this
106/// limitation in the build system.
107///
108/// This has an unfortunate side-effect that all contracts will have a function
109/// in the resulting WASM named `_`, however this function won't be rendered in
110/// the contract specification. The overhead of this is very minimal on file
111/// size.
112///
113/// See https://github.com/stellar/rs-soroban-sdk/issues/383 for more details.
114#[cfg(target_family = "wasm")]
115#[export_name = "_"]
116fn __link_sections() {
117    #[link_section = "contractenvmetav0"]
118    static __ENV_META_XDR: [u8; env::internal::meta::XDR.len()] = env::internal::meta::XDR;
119
120    soroban_sdk_macros::contractmetabuiltin!();
121}
122
123// Re-exports of dependencies used by macros.
124#[doc(hidden)]
125pub mod reexports_for_macros {
126    pub use ::bytes_lit;
127    #[cfg(any(test, feature = "testutils"))]
128    pub use ::ctor;
129}
130
131/// Assert in contract asserts that the contract is currently executing within a
132/// contract. The macro maps to code when testutils are enabled or in tests,
133/// otherwise maps to nothing.
134#[macro_export]
135macro_rules! assert_in_contract {
136    ($env:expr $(,)?) => {{
137        {
138            #[cfg(any(test, feature = "testutils"))]
139            assert!(
140                ($env).in_contract(),
141                "this function is not accessible outside of a contract, wrap \
142                the call with `env.as_contract()` to access it from a \
143                particular contract"
144            );
145        }
146    }};
147}
148
149/// Create a short [Symbol] constant with the given string.
150///
151/// A short symbol's maximum length is 9 characters. For longer symbols, use
152/// [Symbol::new] to create the symbol at runtime.
153///
154/// Valid characters are `a-zA-Z0-9_`.
155///
156/// The [Symbol] is generated at compile time and returned as a const.
157///
158/// ### Examples
159///
160/// ```
161/// use soroban_sdk::{symbol_short, Symbol};
162///
163/// let symbol = symbol_short!("a_str");
164/// assert_eq!(symbol, symbol_short!("a_str"));
165/// ```
166pub use soroban_sdk_macros::symbol_short;
167
168/// Generates conversions from the repr(u32) enum from/into an `Error`.
169///
170/// There are some constraints on the types that are supported:
171/// - Enum must derive `Copy`.
172/// - Enum variants must have an explicit integer literal.
173/// - Enum variants must have a value convertible to u32.
174///
175/// Includes the type in the contract spec so that clients can generate bindings
176/// for the type.
177///
178/// ### Examples
179///
180/// Defining an error and capturing errors using the `try_` variant.
181///
182/// ```
183/// use soroban_sdk::{contract, contracterror, contractimpl, Env};
184///
185/// #[contracterror]
186/// #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
187/// #[repr(u32)]
188/// pub enum Error {
189///     MyError = 1,
190///     AnotherError = 2,
191/// }
192///
193/// #[contract]
194/// pub struct Contract;
195///
196/// #[contractimpl]
197/// impl Contract {
198///     pub fn causeerror(env: Env) -> Result<(), Error> {
199///         Err(Error::MyError)
200///     }
201/// }
202///
203/// #[test]
204/// fn test() {
205/// # }
206/// # #[cfg(feature = "testutils")]
207/// # fn main() {
208///     let env = Env::default();
209///
210///     // Register the contract defined in this crate.
211///     let contract_id = env.register(Contract, ());
212///
213///     // Create a client for calling the contract.
214///     let client = ContractClient::new(&env, &contract_id);
215///
216///     // Invoke contract causeerror function, but use the try_ variant that
217///     // will capture the error so we can inspect.
218///     let result = client.try_causeerror();
219///     assert_eq!(result, Err(Ok(Error::MyError)));
220/// }
221/// # #[cfg(not(feature = "testutils"))]
222/// # fn main() { }
223/// ```
224///
225/// Testing invocations that cause errors with `should_panic` instead of `try_`.
226///
227/// ```should_panic
228/// # use soroban_sdk::{contract, contracterror, contractimpl, Env};
229/// #
230/// # #[contracterror]
231/// # #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
232/// # #[repr(u32)]
233/// # pub enum Error {
234/// #     MyError = 1,
235/// #     AnotherError = 2,
236/// # }
237/// #
238/// # #[contract]
239/// # pub struct Contract;
240/// #
241/// # #[contractimpl]
242/// # impl Contract {
243/// #     pub fn causeerror(env: Env) -> Result<(), Error> {
244/// #         Err(Error::MyError)
245/// #     }
246/// # }
247/// #
248/// #[test]
249/// #[should_panic(expected = "ContractError(1)")]
250/// fn test() {
251/// # panic!("ContractError(1)");
252/// # }
253/// # #[cfg(feature = "testutils")]
254/// # fn main() {
255///     let env = Env::default();
256///
257///     // Register the contract defined in this crate.
258///     let contract_id = env.register(Contract, ());
259///
260///     // Create a client for calling the contract.
261///     let client = ContractClient::new(&env, &contract_id);
262///
263///     // Invoke contract causeerror function.
264///     client.causeerror();
265/// }
266/// # #[cfg(not(feature = "testutils"))]
267/// # fn main() { }
268/// ```
269pub use soroban_sdk_macros::contracterror;
270
271/// Import a contract from its WASM file, generating a client, types, and
272/// constant holding the contract file.
273///
274/// The path given is relative to the workspace root, and not the current
275/// file.
276///
277/// Generates in the current module:
278/// - A `Contract` trait that matches the contracts interface.
279/// - A `ContractClient` struct that has functions for each function in the
280/// contract.
281/// - Types for all contract types defined in the contract.
282///
283/// ### Examples
284///
285/// ```ignore
286/// use soroban_sdk::{contractimpl, BytesN, Env, Symbol};
287///
288/// mod contract_a {
289///     soroban_sdk::contractimport!(file = "contract_a.wasm");
290/// }
291///
292/// pub struct ContractB;
293///
294/// #[contractimpl]
295/// impl ContractB {
296///     pub fn add_with(env: Env, contract_id: BytesN<32>, x: u32, y: u32) -> u32 {
297///         let client = contract_a::ContractClient::new(&env, contract_id);
298///         client.add(&x, &y)
299///     }
300/// }
301///
302/// #[test]
303/// fn test() {
304///     let env = Env::default();
305///
306///     // Register contract A using the imported WASM.
307///     let contract_a_id = env.register_contract_wasm(None, contract_a::WASM);
308///
309///     // Register contract B defined in this crate.
310///     let contract_b_id = env.register(ContractB, ());
311///
312///     // Create a client for calling contract B.
313///     let client = ContractBClient::new(&env, &contract_b_id);
314///
315///     // Invoke contract B via its client.
316///     let sum = client.add_with(&contract_a_id, &5, &7);
317///     assert_eq!(sum, 12);
318/// }
319/// ```
320pub use soroban_sdk_macros::contractimport;
321
322/// Marks a type as being the type that contract functions are attached for.
323///
324/// Use `#[contractimpl]` on impl blocks of this type to make those functions
325/// contract functions.
326///
327/// Note that a crate only ever exports a single contract. While there can be
328/// multiple types in a crate with `#[contract]`, when built as a wasm file and
329/// deployed the combination of all contract functions and all contracts within
330/// a crate will be seen as a single contract.
331///
332/// ### Examples
333///
334/// Define a contract with one function, `hello`, and call it from within a test
335/// using the generated client.
336///
337/// ```
338/// use soroban_sdk::{contract, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
339///
340/// #[contract]
341/// pub struct HelloContract;
342///
343/// #[contractimpl]
344/// impl HelloContract {
345///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
346///         vec![&env, symbol_short!("Hello"), to]
347///     }
348/// }
349///
350/// #[test]
351/// fn test() {
352/// # }
353/// # #[cfg(feature = "testutils")]
354/// # fn main() {
355///     let env = Env::default();
356///     let contract_id = env.register(HelloContract, ());
357///     let client = HelloContractClient::new(&env, &contract_id);
358///
359///     let words = client.hello(&symbol_short!("Dev"));
360///
361///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
362/// }
363/// # #[cfg(not(feature = "testutils"))]
364/// # fn main() { }
365/// ```
366pub use soroban_sdk_macros::contract;
367
368/// Exports the publicly accessible functions to the Soroban environment.
369///
370/// Functions that are publicly accessible in the implementation are invocable
371/// by other contracts, or directly by transactions, when deployed.
372///
373/// ### Examples
374///
375/// Define a contract with one function, `hello`, and call it from within a test
376/// using the generated client.
377///
378/// ```
379/// use soroban_sdk::{contract, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
380///
381/// #[contract]
382/// pub struct HelloContract;
383///
384/// #[contractimpl]
385/// impl HelloContract {
386///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
387///         vec![&env, symbol_short!("Hello"), to]
388///     }
389/// }
390///
391/// #[test]
392/// fn test() {
393/// # }
394/// # #[cfg(feature = "testutils")]
395/// # fn main() {
396///     let env = Env::default();
397///     let contract_id = env.register(HelloContract, ());
398///     let client = HelloContractClient::new(&env, &contract_id);
399///
400///     let words = client.hello(&symbol_short!("Dev"));
401///
402///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
403/// }
404/// # #[cfg(not(feature = "testutils"))]
405/// # fn main() { }
406/// ```
407pub use soroban_sdk_macros::contractimpl;
408
409/// Adds a serialized SCMetaEntry::SCMetaV0 to the WASM contracts custom section
410/// under the section name 'contractmetav0'. Contract developers can use this to
411/// append metadata to their contract.
412///
413/// ### Examples
414///
415/// ```
416/// use soroban_sdk::{contract, contractimpl, contractmeta, vec, symbol_short, BytesN, Env, Symbol, Vec};
417///
418/// contractmeta!(key="desc", val="hello world contract");
419///
420/// #[contract]
421/// pub struct HelloContract;
422///
423/// #[contractimpl]
424/// impl HelloContract {
425///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
426///         vec![&env, symbol_short!("Hello"), to]
427///     }
428/// }
429///
430///
431/// #[test]
432/// fn test() {
433/// # }
434/// # #[cfg(feature = "testutils")]
435/// # fn main() {
436///     let env = Env::default();
437///     let contract_id = env.register(HelloContract, ());
438///     let client = HelloContractClient::new(&env, &contract_id);
439///
440///     let words = client.hello(&symbol_short!("Dev"));
441///
442///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
443/// }
444/// # #[cfg(not(feature = "testutils"))]
445/// # fn main() { }
446/// ```
447pub use soroban_sdk_macros::contractmeta;
448
449/// Generates conversions from the struct/enum from/into a `Val`.
450///
451/// There are some constraints on the types that are supported:
452/// - Enums with integer values must have an explicit integer literal for every
453/// variant.
454/// - Enums with unit variants are supported.
455/// - Enums with tuple-like variants with a maximum of one tuple field are
456/// supported. The tuple field must be of a type that is also convertible to and
457/// from `Val`.
458/// - Enums with struct-like variants are not supported.
459/// - Structs are supported. All fields must be of a type that is also
460/// convertible to and from `Val`.
461/// - All variant names, field names, and type names must be 10-characters or
462/// less in length.
463///
464/// Includes the type in the contract spec so that clients can generate bindings
465/// for the type.
466///
467/// ### Examples
468///
469/// Defining a contract type that is a struct and use it in a contract.
470///
471/// ```
472/// #![no_std]
473/// use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Env, Symbol};
474///
475/// #[contracttype]
476/// #[derive(Clone, Default, Debug, Eq, PartialEq)]
477/// pub struct State {
478///     pub count: u32,
479///     pub last_incr: u32,
480/// }
481///
482/// #[contract]
483/// pub struct Contract;
484///
485/// #[contractimpl]
486/// impl Contract {
487///     /// Increment increments an internal counter, and returns the value.
488///     pub fn increment(env: Env, incr: u32) -> u32 {
489///         // Get the current count.
490///         let mut state = Self::get_state(env.clone());
491///
492///         // Increment the count.
493///         state.count += incr;
494///         state.last_incr = incr;
495///
496///         // Save the count.
497///         env.storage().persistent().set(&symbol_short!("STATE"), &state);
498///
499///         // Return the count to the caller.
500///         state.count
501///     }
502///
503///     /// Return the current state.
504///     pub fn get_state(env: Env) -> State {
505///         env.storage().persistent()
506///             .get(&symbol_short!("STATE"))
507///             .unwrap_or_else(|| State::default()) // If no value set, assume 0.
508///     }
509/// }
510///
511/// #[test]
512/// fn test() {
513/// # }
514/// # #[cfg(feature = "testutils")]
515/// # fn main() {
516///     let env = Env::default();
517///     let contract_id = env.register(Contract, ());
518///     let client = ContractClient::new(&env, &contract_id);
519///
520///     assert_eq!(client.increment(&1), 1);
521///     assert_eq!(client.increment(&10), 11);
522///     assert_eq!(
523///         client.get_state(),
524///         State {
525///             count: 11,
526///             last_incr: 10,
527///         },
528///     );
529/// }
530/// # #[cfg(not(feature = "testutils"))]
531/// # fn main() { }
532/// ```
533///
534/// Defining contract types that are three different types of enums and using
535/// them in a contract.
536///
537/// ```
538/// #![no_std]
539/// use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Symbol, Env};
540///
541/// /// A tuple enum is stored as a two-element vector containing the name of
542/// /// the enum variant as a Symbol, then the value in the tuple.
543/// #[contracttype]
544/// #[derive(Clone, Debug, Eq, PartialEq)]
545/// pub enum Color {
546///     Red(Intensity),
547///     Blue(Shade),
548/// }
549///
550/// /// A unit enum is stored as a single-element vector containing the name of
551/// /// the enum variant as a Symbol.
552/// #[contracttype]
553/// #[derive(Clone, Debug, Eq, PartialEq)]
554/// pub enum Shade {
555///     Light,
556///     Dark,
557/// }
558///
559/// /// An integer enum is stored as its integer value.
560/// #[contracttype]
561/// #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
562/// #[repr(u32)]
563/// pub enum Intensity {
564///     Low = 1,
565///     High = 2,
566/// }
567///
568/// #[contract]
569/// pub struct Contract;
570///
571/// #[contractimpl]
572/// impl Contract {
573///     /// Set the color.
574///     pub fn set(env: Env, c: Color) {
575///         env.storage().persistent().set(&symbol_short!("COLOR"), &c);
576///     }
577///
578///     /// Get the color.
579///     pub fn get(env: Env) -> Option<Color> {
580///         env.storage().persistent()
581///             .get(&symbol_short!("COLOR"))
582///     }
583/// }
584///
585/// #[test]
586/// fn test() {
587/// # }
588/// # #[cfg(feature = "testutils")]
589/// # fn main() {
590///     let env = Env::default();
591///     let contract_id = env.register(Contract, ());
592///     let client = ContractClient::new(&env, &contract_id);
593///
594///     assert_eq!(client.get(), None);
595///
596///     client.set(&Color::Red(Intensity::High));
597///     assert_eq!(client.get(), Some(Color::Red(Intensity::High)));
598///
599///     client.set(&Color::Blue(Shade::Light));
600///     assert_eq!(client.get(), Some(Color::Blue(Shade::Light)));
601/// }
602/// # #[cfg(not(feature = "testutils"))]
603/// # fn main() { }
604/// ```
605pub use soroban_sdk_macros::contracttype;
606
607/// Generates a type that helps build function args for a contract trait.
608pub use soroban_sdk_macros::contractargs;
609
610/// Generates a client for a contract trait.
611///
612/// Can be used to create clients for contracts that live outside the current
613/// crate, using a trait that has been published as a standard or shared
614/// interface.
615///
616/// Primarily useful when needing to generate a client for someone elses
617/// contract where they have only shared a trait interface.
618///
619/// Note that [`contractimpl`] also automatically generates a client, and so it
620/// is unnecessary to use [`contractclient`] for contracts that live in the
621/// current crate.
622///
623/// Note that [`contractimport`] also automatically generates a client when
624/// importing someone elses contract where they have shared a .wasm file.
625///
626/// ### Examples
627///
628/// ```
629/// use soroban_sdk::{contract, contractclient, contractimpl, vec, symbol_short, BytesN, Env, Symbol, Vec};
630///
631/// #[contractclient(name = "Client")]
632/// pub trait HelloInteface {
633///     fn hello(env: Env, to: Symbol) -> Vec<Symbol>;
634/// }
635///
636/// #[contract]
637/// pub struct HelloContract;
638///
639/// #[contractimpl]
640/// impl HelloContract {
641///     pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
642///         vec![&env, symbol_short!("Hello"), to]
643///     }
644/// }
645///
646/// #[test]
647/// fn test() {
648/// # }
649/// # #[cfg(feature = "testutils")]
650/// # fn main() {
651///     let env = Env::default();
652///
653///     // Register the hello contract.
654///     let contract_id = env.register(HelloContract, ());
655///
656///     // Create a client for the hello contract, that was constructed using
657///     // the trait.
658///     let client = Client::new(&env, &contract_id);
659///
660///     let words = client.hello(&symbol_short!("Dev"));
661///
662///     assert_eq!(words, vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),]);
663/// }
664/// # #[cfg(not(feature = "testutils"))]
665/// # fn main() { }
666pub use soroban_sdk_macros::contractclient;
667
668/// Generates a contract spec for a trait or impl.
669///
670/// Note that [`contractimpl`] also generates a contract spec and it is in most
671/// cases not necessary to use this macro.
672#[doc(hidden)]
673pub use soroban_sdk_macros::contractspecfn;
674
675/// Import a contract from its WASM file, generating a constant holding the
676/// contract file.
677///
678/// Note that [`contractimport`] also automatically imports the contract file
679/// into a constant, and so it is usually unnecessary to use [`contractfile`]
680/// directly, unless you specifically want to only load the contract file
681/// without generating a client for it.
682pub use soroban_sdk_macros::contractfile;
683
684/// Panic with the given error.
685///
686/// The first argument in the list must be a reference to an [Env].
687///
688/// The second argument is an error value. The error value will be given to any
689/// calling contract.
690///
691/// Equivalent to `panic!`, but with an error value instead of a string. The
692/// error value will be given to any calling contract.
693///
694/// See [`contracterror`] for how to define an error type.
695#[macro_export]
696macro_rules! panic_with_error {
697    ($env:expr, $error:expr) => {{
698        $env.panic_with_error($error);
699    }};
700}
701
702#[doc(hidden)]
703#[deprecated(note = "use panic_with_error!")]
704#[macro_export]
705macro_rules! panic_error {
706    ($env:expr, $error:expr) => {{
707        $crate::panic_with_error!($env, $error);
708    }};
709}
710
711/// An internal panic! variant that avoids including the string
712/// when building for wasm (since it's just pointless baggage).
713#[cfg(target_family = "wasm")]
714macro_rules! sdk_panic {
715    ($_msg:literal) => {
716        panic!()
717    };
718    () => {
719        panic!()
720    };
721}
722#[cfg(not(target_family = "wasm"))]
723macro_rules! sdk_panic {
724    ($msg:literal) => {
725        panic!($msg)
726    };
727    () => {
728        panic!()
729    };
730}
731
732/// Assert a condition and panic with the given error if it is false.
733///
734/// The first argument in the list must be a reference to an [Env].
735///
736/// The second argument is an expression that if resolves to `false` will cause
737/// a panic with the error in the third argument.
738///
739/// The third argument is an error value. The error value will be given to any
740/// calling contract.
741///
742/// Equivalent to `assert!`, but with an error value instead of a string. The
743/// error value will be given to any calling contract.
744///
745/// See [`contracterror`] for how to define an error type.
746#[macro_export]
747macro_rules! assert_with_error {
748    ($env:expr, $cond:expr, $error:expr) => {{
749        if !($cond) {
750            $crate::panic_with_error!($env, $error);
751        }
752    }};
753}
754
755#[doc(hidden)]
756pub mod unwrap;
757
758mod env;
759
760mod address;
761mod symbol;
762
763pub use env::{ConversionError, Env};
764
765/// Raw value of the Soroban smart contract platform that types can be converted
766/// to and from for storing, or passing between contracts.
767///
768pub use env::Val;
769
770/// Used to do conversions between values in the Soroban environment.
771pub use env::FromVal;
772/// Used to do conversions between values in the Soroban environment.
773pub use env::IntoVal;
774/// Used to do conversions between values in the Soroban environment.
775pub use env::TryFromVal;
776/// Used to do conversions between values in the Soroban environment.
777pub use env::TryIntoVal;
778
779// Used by generated code only.
780#[doc(hidden)]
781pub use env::EnvBase;
782#[doc(hidden)]
783pub use env::Error;
784#[doc(hidden)]
785pub use env::MapObject;
786#[doc(hidden)]
787pub use env::SymbolStr;
788#[doc(hidden)]
789pub use env::VecObject;
790
791mod try_from_val_for_contract_fn;
792#[doc(hidden)]
793#[allow(deprecated)]
794pub use try_from_val_for_contract_fn::TryFromValForContractFn;
795
796#[doc(hidden)]
797#[deprecated(note = "use storage")]
798pub mod data {
799    #[doc(hidden)]
800    #[deprecated(note = "use storage::Storage")]
801    pub use super::storage::Storage as Data;
802}
803pub mod auth;
804mod bytes;
805pub mod crypto;
806pub mod deploy;
807mod error;
808pub use error::InvokeError;
809pub mod events;
810pub use events::Topics;
811pub mod iter;
812pub mod ledger;
813pub mod logs;
814mod map;
815pub mod prng;
816pub mod storage;
817pub mod token;
818mod vec;
819pub use address::Address;
820pub use bytes::{Bytes, BytesN};
821pub use map::Map;
822pub use symbol::Symbol;
823pub use vec::Vec;
824mod num;
825pub use num::{Duration, Timepoint, I256, U256};
826mod string;
827pub use string::String;
828mod tuple;
829
830mod constructor_args;
831pub use constructor_args::ConstructorArgs;
832
833pub mod xdr;
834
835pub mod testutils;
836
837mod arbitrary_extra;
838
839mod tests;