1use ethers::utils::hex;
4use fvm_shared::{address::Address, econ::TokenAmount};
5use recall_ipc_types::EthAddress;
6use serde::de::Error as SerdeError;
7use serde::{Deserialize, Serialize, Serializer};
8use std::str::FromStr;
9
10pub mod address;
11pub mod checkpoint;
12pub mod cross;
13pub mod error;
14pub mod gateway;
15#[cfg(feature = "fil-actor")]
16mod runtime;
17pub mod subnet;
18pub mod subnet_id;
19pub mod validator;
20
21pub mod evm;
22pub mod merkle;
23pub mod staking;
24
25pub fn eth_to_fil_amount(amount: ðers::types::U256) -> anyhow::Result<TokenAmount> {
27 let v = fvm_shared::bigint::BigInt::from_str(&amount.to_string())?;
28 Ok(TokenAmount::from_atto(v))
29}
30
31pub fn ethers_address_to_fil_address(addr: ðers::types::Address) -> anyhow::Result<Address> {
32 let raw_addr = format!("{addr:?}");
33 log::debug!("raw evm subnet addr: {raw_addr:}");
34
35 let eth_addr = EthAddress::from_str(&raw_addr)?;
36 Ok(Address::from(eth_addr))
37}
38
39pub struct HumanReadable;
41
42#[macro_export]
43macro_rules! serialise_human_readable_str {
44 ($typ:ty) => {
45 impl serde_with::SerializeAs<$typ> for $crate::HumanReadable {
46 fn serialize_as<S>(value: &$typ, serializer: S) -> Result<S::Ok, S::Error>
47 where
48 S: serde::Serializer,
49 {
50 if serializer.is_human_readable() {
51 value.to_string().serialize(serializer)
52 } else {
53 value.serialize(serializer)
54 }
55 }
56 }
57 };
58}
59
60#[macro_export]
61macro_rules! deserialize_human_readable_str {
62 ($typ:ty) => {
63 use serde::de::Error as DeserializeError;
64 use serde::{Deserialize, Serialize};
65
66 impl<'de> serde_with::DeserializeAs<'de, $typ> for $crate::HumanReadable {
67 fn deserialize_as<D>(deserializer: D) -> Result<$typ, D::Error>
68 where
69 D: serde::de::Deserializer<'de>,
70 {
71 if deserializer.is_human_readable() {
72 let s = String::deserialize(deserializer)?;
73 <$typ>::from_str(&s).map_err(|_| {
74 D::Error::custom(format!(
75 "cannot parse from str {}",
76 core::any::type_name::<$typ>()
77 ))
78 })
79 } else {
80 <$typ>::deserialize(deserializer)
81 }
82 }
83 }
84 };
85}
86
87#[macro_export]
88macro_rules! as_human_readable_str {
89 ($typ:ty) => {
90 $crate::serialise_human_readable_str!($typ);
91 $crate::deserialize_human_readable_str!($typ);
92 };
93}
94
95impl serde_with::SerializeAs<Vec<u8>> for HumanReadable {
96 fn serialize_as<S>(source: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
97 where
98 S: Serializer,
99 {
100 if serializer.is_human_readable() {
101 hex::encode(source).serialize(serializer)
102 } else {
103 source.serialize(serializer)
104 }
105 }
106}
107
108impl<'de> serde_with::DeserializeAs<'de, Vec<u8>> for HumanReadable {
109 fn deserialize_as<D>(deserializer: D) -> Result<Vec<u8>, D::Error>
110 where
111 D: serde::de::Deserializer<'de>,
112 {
113 if deserializer.is_human_readable() {
114 let s = String::deserialize(deserializer)?;
115 Ok(hex::decode(s)
116 .map_err(|e| D::Error::custom(format!("cannot parse from str {e}")))?)
117 } else {
118 Vec::<u8>::deserialize(deserializer)
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use crate::HumanReadable;
126 use serde::{Deserialize, Serialize};
127 use serde_with::serde_as;
128
129 #[test]
130 fn test_human_readable() {
131 #[serde_as]
132 #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
133 struct T {
134 #[serde_as(as = "HumanReadable")]
135 bytes: Vec<u8>,
136 }
137
138 let t = T {
139 bytes: vec![1, 2, 3, 4],
140 };
141
142 let serialized_t = serde_json::to_vec(&t).unwrap();
143 let dserialized_t = serde_json::from_slice(&serialized_t).unwrap();
144 assert_eq!(t, dserialized_t);
145
146 let serialized_t = fvm_ipld_encoding::to_vec(&t).unwrap();
147 let dserialized_t = fvm_ipld_encoding::from_slice(&serialized_t).unwrap();
148 assert_eq!(t, dserialized_t);
149 }
150}