1use rs_zephyr_common::{http::AgnosticRequest, RelayedMessageRequest};
2use serde::Serialize;
3use stellar_xdr::next::{Limits, ReadXdr};
4
5use crate::{database::{Database, DatabaseInteract}, external::{conclude_host, read_ledger_meta, tx_send_message}, logger::EnvLogger, Condition, MetaReader, SdkError, TableRows};
6
7
8#[derive(Clone)]
10pub struct EnvClient {
11 xdr: Option<stellar_xdr::next::LedgerCloseMeta>,
12 inner_soroban_host: soroban_sdk::Env,
13}
14
15
16impl EnvClient {
17 pub fn log(&self) -> EnvLogger {
19 EnvLogger
20 }
21
22 pub fn soroban(&self) -> &soroban_sdk::Env {
24 &self.inner_soroban_host
25 }
26
27 pub(crate) fn message_relay(message: impl Serialize) {
28 let serialized = bincode::serialize(&message).unwrap();
29
30 let res = unsafe {
31 tx_send_message(
32 serialized.as_ptr() as i64,
33 serialized.len() as i64
34 )
35 };
36
37 SdkError::express_from_status(res).unwrap()
38 }
39
40 pub fn send_web_request(&self, request: AgnosticRequest) {
42 let message = RelayedMessageRequest::Http(request);
43
44 Self::message_relay(message)
45 }
46
47 pub fn read<T: DatabaseInteract>(&self) -> Vec<T> {
53 T::read_to_rows(&self)
54 }
55
56 pub fn put<T: DatabaseInteract>(&self, row: &T) {
62 row.put(&self)
63 }
64
65 pub fn update<T: DatabaseInteract>(&self, row: &T, conditions: &[Condition]) {
71 row.update(&self, conditions)
72 }
73
74 pub fn db_write(&self, table_name: &str, columns: &[&str], segments: &[&[u8]]) -> Result<(), SdkError> {
76 Database::write_table(table_name, columns, segments)
77 }
78
79 pub fn db_update(&self, table_name: &str, columns: &[&str], segments: &[&[u8]], conditions: &[Condition]) -> Result<(), SdkError> {
81 Database::update_table(table_name, columns, segments, conditions)
82 }
83
84 pub fn db_read(&self, table_name: &str, columns: &[&str]) -> Result<TableRows, SdkError> {
86 Database::read_table(table_name, columns)
87 }
88
89 pub fn reader(&self) -> MetaReader {
91 let meta = &self.xdr;
92
93 if let Some(meta) = meta {
94 MetaReader::new(meta)
95 } else {
96 panic!("Internal SDK error") }
98 }
99
100 pub fn new() -> Self {
103 let (offset, size) = unsafe { read_ledger_meta() };
104
105 let ledger_meta = {
106 let memory = 0 as *const u8;
107 let slice = unsafe {
108 let start = memory.offset(offset as isize);
109 core::slice::from_raw_parts(start, size as usize)
110 };
111
112 Some(stellar_xdr::next::LedgerCloseMeta::from_xdr(slice, Limits::none()).unwrap())
113 };
114
115 Self { xdr: ledger_meta, inner_soroban_host: soroban_sdk::Env::default() }
116 }
117
118 pub fn empty() -> Self {
120 Self { xdr: None, inner_soroban_host: soroban_sdk::Env::default() }
121 }
122
123 pub fn conclude<T: Serialize>(&self, result: T) {
133 let v = bincode::serialize(&serde_json::to_string(&result).unwrap()).unwrap();
134
135 unsafe {
136 conclude_host(v.as_ptr() as i64, v.len() as i64)
137 }
138 }
139}