rs_zephyr_sdk/
ledger.rs

1use rs_zephyr_common::{wrapping::WrappedMaxBytes, ContractDataEntry};
2use soroban_sdk::{Map, TryFromVal, Val};
3use stellar_xdr::next::{Limits, ScVal, WriteXdr};
4use crate::{env::EnvClient, external::{read_contract_data_entry_by_contract_id_and_key, read_contract_entries_by_contract, read_contract_entries_by_contract_to_env, read_contract_instance}, SdkError};
5
6
7impl EnvClient {
8    fn express_and_deser_entry(status: i64, offset: i64, size: i64) -> Result<Option<ContractDataEntry>, SdkError> {
9        SdkError::express_from_status(status)?;
10
11        let memory: *const u8 = offset as *const u8;
12        let slice = unsafe { core::slice::from_raw_parts(memory, size as usize) };
13
14        bincode::deserialize::<Option<ContractDataEntry>>(slice).map_err(|_| SdkError::Conversion)
15    }
16    
17    /// Returns the instance object of a certain contract from
18    /// the host's ledger.
19    pub fn read_contract_instance(&self, contract: [u8; 32]) -> Result<Option<ContractDataEntry>, SdkError> {
20        let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
21        let (status, offset, size) = unsafe { read_contract_instance(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3]) };
22
23        Self::express_and_deser_entry(status, offset, size)
24    }
25
26    /// Returns the requested entry object of a certain contract 
27    /// from the host's ledger.
28    pub fn read_contract_entry_by_key(&self, contract: [u8; 32], key: ScVal) -> Result<Option<ContractDataEntry>, SdkError> {
29        let key_bytes = key.to_xdr(Limits::none()).unwrap();
30        let (offset, size) = (key_bytes.as_ptr() as i64, key_bytes.len() as i64);
31
32        let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
33        let (status, inbound_offset, inbound_size) = unsafe {
34            read_contract_data_entry_by_contract_id_and_key(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3], offset, size)
35        };
36
37        Self::express_and_deser_entry(status, inbound_offset, inbound_size)
38    }
39
40    /// Returns all the entry objects of a certain contract 
41    /// from the host's ledger.
42    pub fn read_contract_entries(&self, contract: [u8; 32]) -> Result<Vec<ContractDataEntry>, SdkError> {
43        let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
44        
45        let (status, offset, size) = unsafe { read_contract_entries_by_contract(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3]) };
46
47        SdkError::express_from_status(status)?;
48
49        let memory: *const u8 = offset as *const u8;
50        let slice = unsafe { core::slice::from_raw_parts(memory, size as usize) };
51
52        bincode::deserialize::<Vec<ContractDataEntry>>(slice).map_err(|_| SdkError::Conversion)
53    }
54
55    /// Returns all the entry objects of a certain contract 
56    /// from the host's ledger. This function retuns an iteraror
57    /// over Soroban host objects, and should be used along with the
58    /// Soroban SDK.
59    pub fn read_contract_entries_to_env(&self, env: &soroban_sdk::Env, contract: [u8; 32]) -> Result<Map<Val, Val>, SdkError> {
60        let contract_parts = WrappedMaxBytes::array_to_max_parts::<4>(&contract);
61        let (status, mapobject ) = unsafe { read_contract_entries_by_contract_to_env(contract_parts[0], contract_parts[1], contract_parts[2], contract_parts[3]) };
62        SdkError::express_from_status(status)?;
63
64        let map = Map::try_from_val(env, &Val::from_payload(mapobject as u64)).unwrap();
65        Ok(map)
66    }
67}