cma_rust_parser/
helpers.rs

1use hex;
2use once_cell::sync::Lazy;
3use ethers_core::types::{Address};
4use json::{JsonValue, object};
5use crate::parser::CmaVoucher;
6
7pub fn hex_to_string(hex: &str) -> Result<String, Box<dyn std::error::Error>> {
8    let hexstr = hex.strip_prefix("0x").unwrap_or(hex);
9    let bytes = hex::decode(hexstr).map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
10    let s = String::from_utf8(bytes).map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
11    Ok(s)
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Portals {
16    ERC1155BatchPortal,
17    ERC1155SinglePortal,
18    ERC20Portal,
19    ERC721Portal,
20    EtherPortal,
21    None,
22}
23
24pub struct CartesiAddresses {
25    pub erc1155_batch_portal: String,
26    pub erc1155_single_portal: String,
27    pub erc20_portal: String,
28    pub erc721_portal: String,
29    pub ether_portal: String,
30}
31
32pub static CARTESI_ADDRESSES: Lazy<CartesiAddresses> = Lazy::new(|| CartesiAddresses {
33    erc1155_batch_portal: "0xc700A2e5531E720a2434433b6ccf4c0eA2400051".to_string(),
34    erc1155_single_portal: "0xc700A261279aFC6F755A3a67D86ae43E2eBD0051".to_string(),
35    erc20_portal: "0xc700D6aDd016eECd59d989C028214Eaa0fCC0051".to_string(),
36    erc721_portal: "0xc700d52F5290e978e9CAe7D1E092935263b60051".to_string(),
37    ether_portal: "0xc70076a466789B595b50959cdc261227F0D70051".to_string(),
38});
39
40pub trait PortalMatcher {
41    fn match_portal(&self, addr: &str) -> Portals;
42    fn get_portal_address(&self, portal: Portals) -> Option<&str>;
43}
44
45impl PortalMatcher for CartesiAddresses {
46    fn match_portal(&self, addr: &str) -> Portals {
47        let caller_address = addr.trim().to_lowercase();
48
49        if caller_address == self.erc1155_batch_portal.to_lowercase() {
50            Portals::ERC1155BatchPortal
51        } else if caller_address == self.erc1155_single_portal.to_lowercase() {
52            Portals::ERC1155SinglePortal
53        } else if caller_address == self.erc20_portal.to_lowercase() {
54            Portals::ERC20Portal
55        } else if caller_address == self.erc721_portal.to_lowercase() {
56            Portals::ERC721Portal
57        } else if caller_address == self.ether_portal.to_lowercase() {
58            Portals::EtherPortal
59        } else {
60            Portals::None
61        }
62    }
63
64    fn get_portal_address(&self, portal: Portals) -> Option<&str> {
65        match portal {
66            Portals::ERC1155BatchPortal => Some(&self.erc1155_batch_portal),
67            Portals::ERC1155SinglePortal => Some(&self.erc1155_single_portal),
68            Portals::ERC20Portal => Some(&self.erc20_portal),
69            Portals::ERC721Portal => Some(&self.erc721_portal),
70            Portals::EtherPortal => Some(&self.ether_portal),
71            Portals::None => None,
72        }
73    }
74}
75
76pub trait ToAddress {
77    fn to_address(&self) -> Result<Address, String>;
78}
79
80impl ToAddress for str {
81    fn to_address(&self) -> Result<Address, String> {
82        self.parse::<Address>()
83            .map_err(|e| format!("Invalid Ethereum address: {}", e))
84    }
85}
86
87impl ToAddress for String {
88    fn to_address(&self) -> Result<Address, String> {
89        self.as_str().to_address()
90    }
91}
92
93#[allow(dead_code)]
94pub trait ToJson {
95    fn to_json(&self) -> JsonValue;
96}
97
98impl ToJson for CmaVoucher {
99    fn to_json(&self) -> JsonValue {
100        let voucher = object! {
101            "destination" => format!("{}", self.destination),
102            "payload" => format!("{}", self.payload),
103            "value" => format!("{}", self.value),
104        };
105        return voucher;
106    }
107}