1pub mod http;
2pub mod ipfs;
3pub mod kv;
4pub mod sc;
5pub mod sxt;
6pub mod stellar;
7
8use core::panic;
9use std::str::FromStr;
10
11pub use dotenvy;
12pub use web3;
13
14use bytecodec::{
15 bytes::{BytesEncoder, RemainingBytesDecoder},
16 io::{IoDecodeExt, IoEncodeExt},
17 Encode,
18};
19use httpcodec::{BodyDecoder, BodyEncoder, RequestDecoder, ResponseEncoder};
20
21#[no_mangle]
22pub static mut ENV_VAR_PTR: *const u8 = std::ptr::null();
23
24#[no_mangle]
25pub static mut ENV_VAR_LEN: usize = 0;
26
27#[no_mangle]
28pub static mut RES_PTR: *const u8 = std::ptr::null();
29
30pub fn get_args(arg_ptr: *const u8, arg_len: usize) -> String {
32 let arg_str = unsafe {
33 if arg_ptr.is_null() {
34 panic!("ARG_PTR must be set.");
35 }
36
37 let json_bytes = std::slice::from_raw_parts(arg_ptr, arg_len);
38 std::str::from_utf8_unchecked(json_bytes)
39 };
40 arg_str.to_string()
41}
42
43pub fn set_env_context() {
44 let env_var_bytes = unsafe {
45 if ENV_VAR_PTR.is_null() {
46 panic!("ENV_VAR_PTR must be set")
47 }
48 std::slice::from_raw_parts(ENV_VAR_PTR, ENV_VAR_LEN)
49 };
50
51 dotenvy::from_read_override(env_var_bytes).unwrap();
52}
53
54pub fn encode_response(res: http::Response<Vec<u8>>) -> u32 {
55 let (parts, body) = res.into_parts();
56 let version = if parts.version == http::Version::HTTP_10 {
57 httpcodec::HttpVersion::V1_0
58 } else if parts.version == http::Version::HTTP_11 {
59 httpcodec::HttpVersion::V1_1
60 } else {
61 panic!("Only HTTP 1.0 and 1.1 are supported")
62 };
63 let mut enc_res = unsafe {
64 httpcodec::Response::new(
65 version,
66 httpcodec::StatusCode::new_unchecked(parts.status.as_u16()),
67 httpcodec::ReasonPhrase::new_unchecked(parts.status.canonical_reason().unwrap_or("")),
68 body,
69 )
70 };
71 let mut enc_headers = enc_res.header_mut();
72 for header in parts.headers {
73 let name = header
74 .0
75 .map(|name| name.to_string())
76 .unwrap_or("".to_string());
77 let value = header.1.to_str().unwrap();
78 enc_headers.add_field(unsafe { httpcodec::HeaderField::new_unchecked(&name, value) });
79 }
80
81 let mut encoder = ResponseEncoder::<BodyEncoder<BytesEncoder>>::default();
82 encoder.start_encoding(enc_res).unwrap();
83 let mut res_buf = Vec::new();
84 encoder.encode_all(&mut res_buf).unwrap();
85 let mut res_buf_with_len = (res_buf.len() as u32).to_le_bytes().to_vec();
86 res_buf_with_len.append(&mut res_buf);
87 let ptr = res_buf_with_len.as_ptr();
88 std::mem::forget(res_buf_with_len);
89 ptr as u32
90}
91
92pub fn request_from_raw_parts(req_ptr: u32, req_len: u32) -> http::Request<Vec<u8>> {
93 let req_buf = unsafe { std::slice::from_raw_parts(req_ptr as *const u8, req_len as usize) };
94 let mut decoder = RequestDecoder::<BodyDecoder<RemainingBytesDecoder>>::default();
95 let dec_req = decoder.decode_exact(req_buf).unwrap();
96 let mut req = http::Request::builder()
97 .version(match dec_req.http_version() {
98 httpcodec::HttpVersion::V1_0 => http::Version::HTTP_10,
99 httpcodec::HttpVersion::V1_1 => http::Version::HTTP_11,
100 })
101 .method(http::Method::from_str(dec_req.method().as_str()).unwrap())
102 .uri(http::Uri::from_str(dec_req.request_target().as_str()).unwrap());
103 for header in dec_req.header().fields() {
104 req = req.header(header.name(), header.value());
105 }
106
107 let req = req.body(dec_req.into_body()).unwrap();
108 req
109}