Skip to main content

moonramp_lunar_core/
lib.rs

1use std::{
2    error::Error,
3    fmt, mem,
4    os::raw::{c_uchar, c_void},
5};
6
7use serde::{Deserialize, Serialize};
8
9pub use moonramp_core;
10pub use moonramp_wallet;
11
12pub use wee_alloc;
13
14use moonramp_core::{serde, serde_json};
15use moonramp_wallet::{Currency, Wallet};
16
17pub mod gateway;
18
19extern "C" {
20    fn lunar_ptr_len(ptr: *mut c_uchar) -> usize;
21    fn lunar_exit(exit_data_ptr: *mut c_uchar, size: usize);
22}
23
24pub enum LunarExitCode {
25    Success = 0,
26    Failed = 1,
27    Panic = -1,
28}
29
30#[derive(Debug, Deserialize, Serialize)]
31#[serde(crate = "moonramp_core::serde")]
32pub enum LunarError {
33    Crash(String),
34    Serde(String),
35    Wallet(String),
36}
37
38impl fmt::Display for LunarError {
39    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40        write!(f, "{:?}", self)
41    }
42}
43
44impl Error for LunarError {}
45
46#[derive(Debug, Deserialize, Serialize)]
47#[serde(crate = "moonramp_core::serde")]
48pub enum EntryData {
49    Invoice {
50        wallet: Wallet,
51        currency: Currency,
52        amount: f64,
53        user_data: Option<Vec<u8>>,
54    },
55    Sale {
56        wallet: Wallet,
57        currency: Currency,
58        amount: f64,
59        address: String,
60        confirmations: u64,
61        user_data: Option<Vec<u8>>,
62    },
63}
64
65#[derive(Debug, Deserialize, Serialize)]
66#[serde(crate = "moonramp_core::serde")]
67pub enum ExitData {
68    Invoice {
69        wallet: Wallet,
70        pubkey: String,
71        address: String,
72        uri: String,
73        user_data: Option<Vec<u8>>,
74    },
75    Sale {
76        funded: bool,
77        amount: f64,
78        user_data: Option<Vec<u8>>,
79    },
80}
81
82pub trait Program: Default {
83    fn launch(self, entry_data: EntryData) -> Result<ExitData, LunarError>;
84}
85
86pub fn run_lunar_program<P: Program>(
87    entry_data_json: &[u8],
88    prgm: P,
89) -> Result<ExitData, LunarError> {
90    let entry_data: EntryData =
91        serde_json::from_slice(entry_data_json).map_err(|e| LunarError::Serde(e.to_string()))?;
92    prgm.launch(entry_data)
93}
94
95pub fn lunar_core_main<P: Program>(entry_data_ptr: *mut c_uchar, size: usize, prgm: P) -> i32 {
96    let entry_data = unsafe { Vec::from_raw_parts(entry_data_ptr, size, size) };
97    let res = run_lunar_program(entry_data.as_ref(), prgm);
98
99    match (res.is_ok(), serde_json::to_vec(&res)) {
100        (true, Ok(mut exit_data_json)) => {
101            let exit_data_len = exit_data_json.len();
102            let exit_data_ptr = exit_data_json.as_mut_ptr();
103            mem::forget(exit_data_json);
104            unsafe { lunar_exit(exit_data_ptr as *mut c_uchar, exit_data_len) };
105            LunarExitCode::Success as i32
106        }
107        (false, Ok(mut exit_data_json)) => {
108            let exit_data_len = exit_data_json.len();
109            let exit_data_ptr = exit_data_json.as_mut_ptr();
110            mem::forget(exit_data_json);
111            unsafe { lunar_exit(exit_data_ptr as *mut c_uchar, exit_data_len) };
112            LunarExitCode::Failed as i32
113        }
114        (_, Err(err)) => {
115            println!("Lunar-Program Res {:?} Error {:?}", res, err);
116            LunarExitCode::Failed as i32
117        }
118    }
119}
120
121pub fn lunar_core_allocate(size: usize) -> *mut c_void {
122    let mut buf = Vec::with_capacity(size);
123    let ptr = buf.as_mut_ptr();
124    mem::forget(buf);
125    ptr as *mut c_void
126}
127
128pub fn lunar_core_deallocate(ptr: *mut c_void, size: usize) {
129    unsafe {
130        let _drop = Vec::from_raw_parts(ptr as *mut c_uchar, size, size);
131    }
132}