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