rs_zephyr_sdk/
lib.rs

1//! Zephyr Rust SDK
2//! 
3//! The zephyr rust sdk aids developers in writing programs for the
4//! Zephyr Virtual Machine.
5//! 
6//! ## Hello Ledger Example
7//! 
8//! ```
9//! use rs_zephyr_sdk::{bincode, log, stellar_xdr::next::{Limits, WriteXdr}, Condition, DatabaseDerive, DatabaseInteract, EnvClient, ZephyrVal};
10//! 
11//! #[derive(DatabaseDerive, Clone)]
12//! #[with_name("curr_seq")]
13//! struct Sequence {
14//!     pub current: u32,
15//! }
16//! 
17//! #[no_mangle]
18//! pub extern "C" fn on_close() {
19//!    let env = EnvClient::new();
20//!    let reader = env.reader();
21//!
22//!    let sequence = Sequence {
23//!        current: reader.ledger_sequence()
24//!    };
25//!
26//!    if let Some(last) = Sequence::read_to_rows(&env).iter().find(|x| x.current == sequence.current - 1) {
27//!        sequence.update(&env, &[Condition::ColumnEqualTo("current".into(), bincode::serialize(&ZephyrVal::U32(last.current)).unwrap())]);
28//!    } else {
29//!        sequence.put(&env)
30//!    }
31//! }
32//! ```
33//! 
34
35#![warn(missing_docs)]
36
37mod database;
38mod ledger_meta;
39mod symbol;
40mod ledger;
41mod env;
42mod external;
43mod logger;
44
45use rs_zephyr_common::ZephyrStatus;
46use thiserror::Error;
47
48pub use env::EnvClient;
49pub use database::{TableRow, TableRows, DatabaseInteract};
50pub use ledger_meta::MetaReader;
51pub use rs_zephyr_common::ContractDataEntry;
52pub use ledger_meta::EntryChanges;
53pub use soroban_sdk;
54pub use stellar_xdr;
55pub use database::Condition;
56pub use rs_zephyr_common::{ZephyrVal, http::{AgnosticRequest, Method}};
57pub use bincode;
58pub use macros::DatabaseInteract as DatabaseDerive;
59
60fn to_fixed<T, const N: usize>(v: Vec<T>) -> [T; N] {
61    v.try_into()
62        .unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
63}
64
65//extern crate wee_alloc;
66//
67//#[global_allocator]
68//static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
69
70/// Zephyr SDK errors.
71#[derive(Clone, Debug, Copy, Error)]
72#[allow(missing_docs)]
73pub enum SdkError {
74    #[error("Conversion error.")]
75    Conversion,
76
77    #[error("Error in reading database.")]
78    DbRead,
79
80    #[error("Error in writing database.")]
81    DbWrite,
82
83    #[error("No value found on host pseudo store.")]
84    NoValOnStack,
85
86    #[error("Incorrect host configurations.")]
87    HostConfiguration,
88
89    #[error("Unknown error.")]
90    Unknown
91}
92
93impl SdkError {
94    fn express_from_status(status: i64) -> Result<(), Self> {
95        match ZephyrStatus::from(status as u32) {
96            ZephyrStatus::Success => Ok(()),
97            ZephyrStatus::DbReadError => Err(SdkError::DbRead),
98            ZephyrStatus::DbWriteError => Err(SdkError::DbWrite),
99            ZephyrStatus::NoValOnStack => Err(SdkError::NoValOnStack),
100            ZephyrStatus::HostConfiguration => Err(SdkError::HostConfiguration),
101            ZephyrStatus::Unknown => Err(SdkError::Unknown)
102        }
103    }
104}
105
106
107/// Some sparse scval utils.
108/// Note that these might be deprecated in the future.
109#[allow(missing_docs)]
110pub mod utils {
111    use stellar_xdr::next::{Int128Parts, ScMapEntry, ScSymbol, ScVal, ScVec, VecM};
112
113    use crate::SdkError;
114
115    pub fn to_datakey_u32(int: u32) -> ScVal {
116        ScVal::U32(int)
117    }
118
119    pub fn to_datakey_symbol(variant_str: &str) -> ScVal {
120        let tot_s_val = ScVal::Symbol(ScSymbol(variant_str.to_string().try_into().unwrap()));
121
122        ScVal::Vec(Some(ScVec(VecM::try_from(vec![tot_s_val]).unwrap())))
123    }
124
125    pub fn instance_entries(val: &ScVal) -> Option<Vec<ScMapEntry>> {
126        if let ScVal::ContractInstance(instance) = val {
127            if let Some(map) = &instance.storage {
128                return Some(map.to_vec());
129            }
130        }
131
132        None
133    }
134
135    pub fn to_scval_symbol(from: &str) -> Result<ScVal, SdkError> {
136        Ok(ScVal::Symbol(ScSymbol(from.try_into().map_err(|_| SdkError::Conversion)?)))
137    }
138
139    pub fn parts_to_i128(parts: &Int128Parts) -> i128 {
140        ((parts.hi as i128) << 64) | (parts.lo as i128)
141    }
142
143    pub fn to_array<T, const N: usize>(v: Vec<T>) -> [T; N] {
144        v.try_into()
145            .unwrap_or_else(|v: Vec<T>| panic!("Expected a Vec of length {} but it was {}", N, v.len()))
146    }
147}