1extern crate self as lyquor_primitives;
2pub extern crate serde;
3
4use std::fmt;
5use std::sync::Arc;
6
7pub use alloy_primitives::hex;
8pub use alloy_primitives::{self, Address, B256, U32, U64, U128, U256, address, uint};
9pub use blake3;
10pub use bytes::{self, Bytes};
11pub use cb58;
12pub use serde::{Deserialize, Serialize};
13use typed_builder::TypedBuilder;
14
15mod id;
16pub mod oracle;
17pub use id::{LyquidID, LyquidNumber, NodeID, RequiredLyquid};
18
19pub mod arc_option_serde {
21 use super::*;
22 use serde::{Deserialize, Deserializer, Serialize, Serializer};
23
24 pub fn serialize<T, S>(value: &Option<Arc<T>>, serializer: S) -> Result<S::Ok, S::Error>
25 where
26 T: Serialize,
27 S: Serializer,
28 {
29 match value {
30 Some(arc) => Some(arc.as_ref()).serialize(serializer),
31 None => Option::<&T>::None.serialize(serializer),
32 }
33 }
34
35 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Option<Arc<T>>, D::Error>
36 where
37 T: Deserialize<'de>,
38 D: Deserializer<'de>,
39 {
40 let opt = Option::<T>::deserialize(deserializer)?;
41 Ok(opt.map(Arc::new))
42 }
43}
44
45pub type Hash = blake3::Hash;
46
47#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
54pub struct ChainPos(u128);
55
56impl ChainPos {
57 pub const ZERO: Self = Self(0);
58 pub fn new(block_position: u64, block_index: u32) -> Self {
59 Self((block_position as u128) << 32 | (block_index as u128))
60 }
61
62 #[inline(always)]
63 pub fn block(&self) -> u64 {
64 (self.0 >> 32) as u64
65 }
66
67 #[inline(always)]
68 pub fn next_block(&self) -> Self {
69 Self(((self.0 >> 32) + 1) << 32)
70 }
71}
72
73impl fmt::Display for ChainPos {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
75 write!(f, "(block={}, log={})", self.0 >> 32, self.0 as u32)
76 }
77}
78
79impl fmt::Debug for ChainPos {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
81 fmt::Display::fmt(self, f)
82 }
83}
84
85#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug)]
86pub enum InputABI {
87 Lyquor,
88 Eth,
89}
90
91#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
92pub struct HashBytes(Hash);
93
94impl HashBytes {
95 pub fn new(hash: Hash) -> Self {
96 Self(hash)
97 }
98
99 pub fn into_inner(self) -> Hash {
100 self.0
101 }
102}
103
104impl std::ops::Deref for HashBytes {
105 type Target = Hash;
106 fn deref(&self) -> &Hash {
107 &self.0
108 }
109}
110
111impl From<[u8; 32]> for HashBytes {
112 fn from(hash: [u8; 32]) -> Self {
113 Self(hash.into())
114 }
115}
116
117impl From<HashBytes> for [u8; 32] {
118 fn from(hash: HashBytes) -> Self {
119 hash.0.into()
120 }
121}
122
123impl From<Hash> for HashBytes {
124 fn from(hash: Hash) -> Self {
125 Self(hash)
126 }
127}
128
129impl From<HashBytes> for Hash {
130 fn from(hash_bytes: HashBytes) -> Self {
131 hash_bytes.0
132 }
133}
134
135impl Serialize for HashBytes {
136 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137 where
138 S: serde::Serializer,
139 {
140 let bytes: &[u8; 32] = self.0.as_bytes();
141 serializer.serialize_bytes(bytes)
142 }
143}
144
145impl<'de> Deserialize<'de> for HashBytes {
146 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
147 where
148 D: serde::Deserializer<'de>,
149 {
150 use serde::de::Error;
151 let bytes = <Vec<u8>>::deserialize(deserializer)?;
152 if bytes.len() != 32 {
153 return Err(D::Error::custom(format!(
154 "Expected 32 bytes for HashBytes, got {}",
155 bytes.len()
156 )));
157 }
158 let mut array = [0u8; 32];
159 array.copy_from_slice(&bytes);
160 Ok(HashBytes(blake3::Hash::from(array)))
161 }
162}
163
164#[derive(Serialize, Deserialize, PartialEq, Clone, TypedBuilder)]
165pub struct CallParams {
166 #[builder(default = Address::ZERO)]
169 pub origin: Address,
170 pub caller: Address,
172 #[builder(default = GROUP_DEFAULT.into())]
173 pub group: String,
174 pub method: String,
175 pub input: Bytes,
176 #[builder(default = InputABI::Lyquor)]
177 pub abi: InputABI,
178}
179
180impl Eq for CallParams {}
181
182impl fmt::Debug for CallParams {
183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
184 write!(
185 f,
186 "CallParams(caller={}, origin={}, group={}, method={}, input={}, abi={:?})",
187 self.caller,
188 self.origin,
189 self.group,
190 self.method,
191 hex::encode(&self.input),
192 self.abi
193 )
194 }
195}
196
197pub const GROUP_DEFAULT: &str = "main";
198pub const GROUP_NODE: &str = "node";
199pub const GROUP_UPC_PREPARE: &str = "upc::prepare";
200pub const GROUP_UPC_REQ: &str = "upc::request";
201pub const GROUP_UPC_RESP: &str = "upc::response";
202
203pub type LyteLogTopic = B256;
204
205#[derive(Serialize, Deserialize, Clone)]
206pub struct LyteLog {
207 pub topics: [Option<Box<LyteLogTopic>>; 4],
208 pub data: Bytes,
209}
210
211impl LyteLog {
212 pub fn new_from_tagged_value<V: Serialize>(tag: &str, value: &V) -> Self {
213 let topic0 = Box::new(Self::tagged_value_topic(tag));
214 Self {
215 topics: [Some(topic0), None, None, None],
216 data: encode_object(value).into(),
217 }
218 }
219
220 pub fn tagged_value_topic(tag: &str) -> LyteLogTopic {
221 let mut hasher = blake3::Hasher::new();
222 hasher.update(tag.as_bytes());
223 let topic: [u8; 32] = hasher.finalize().into();
224 topic.into()
225 }
226}
227
228#[derive(Serialize, Deserialize, Clone, Debug)]
229pub struct RegisterEvent {
230 pub id: LyquidID,
231 pub deps: Vec<LyquidID>,
232}
233
234impl fmt::Debug for LyteLog {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
236 write!(
237 f,
238 "LyteLog(topics={}, data=<{} bytes>)",
239 self.topics
240 .iter()
241 .map(|t| match t {
242 Some(t) => t.to_string(),
243 None => "_".into(),
244 })
245 .collect::<Vec<_>>()
246 .join(", "),
247 self.data.len()
248 )
249 }
250}
251
252pub fn decode_object<T: for<'a> Deserialize<'a>>(raw: &[u8]) -> Option<T> {
253 postcard::from_bytes(raw).ok()
254}
255
256pub fn encode_object<T: Serialize + ?Sized>(obj: &T) -> Vec<u8> {
257 postcard::to_stdvec(obj).expect("postcard serialization failed")
258}
259
260pub fn encode_object_with_prefix<T: Serialize + ?Sized>(prefix: &[u8], obj: &T) -> Vec<u8> {
261 let mut vec = Vec::with_capacity(prefix.len() + core::mem::size_of_val(obj));
262 vec.extend_from_slice(prefix);
263 postcard::to_io(obj, &mut vec).expect("postcard serialization failed");
264 vec
265}
266
267#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
268pub enum StateCategory {
269 Network,
270 Instance,
271}
272
273#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Copy, Clone)]
274#[serde(rename_all = "camelCase")]
275pub enum ConsoleSink {
276 StdOut,
277 StdErr,
278}
279
280pub fn encode_method_name(cat_prefix: &str, group: &str, method: &str) -> String {
281 let mut output = cat_prefix.to_string();
282 output.push('_');
283 cb58::bs58::encode(group.as_bytes()).onto(&mut output).unwrap();
284 output.push('_');
285 output.push_str(method);
286 output
287}
288
289#[doc(hidden)]
290#[macro_export]
291macro_rules! object_by_fields_ {
292 ($serde_crate: tt, $($var:ident: $type:ty = $val:expr),*) => {{
293 #[allow(non_camel_case_types)]
294 #[derive($crate::Serialize, Clone)]
295 #[serde(crate = $serde_crate)]
296 struct parameters { $($var:$type),* }
297 parameters { $($var: $val),* }
298 }};
299}
300
301#[macro_export]
302macro_rules! object_by_fields {
303 ($($token: tt)*) => {{
304 $crate::object_by_fields_!("lyquor_primitives::serde", $($token)*)
305 }};
306}
307
308#[doc(hidden)]
309#[macro_export]
310macro_rules! encode_by_fields_ {
311 ($serde_crate: tt, $($var:ident: $type:ty = $val:expr),*) => {{
312 $crate::encode_object(&$crate::object_by_fields_!($serde_crate, $($var: $type = $val),*))
313 }};
314 ($serde_crate: tt, $($var:ident: $type:ty),*) => {{
315 $crate::encode_object(&$crate::object_by_fields_!($serde_crate, $($var: $type = $var),*))
316 }};
317}
318
319#[macro_export]
320macro_rules! encode_by_fields {
321 ($($token: tt)*) => {{
322 $crate::encode_by_fields_!("lyquor_primitives::serde", $($token)*)
323 }};
324}
325
326#[macro_export]
327macro_rules! decode_by_fields {
328 ($encoded:expr, $($var:ident: $type:ty),*) => {{
329 #[allow(non_camel_case_types)]
330 #[derive($crate::Deserialize)]
331 #[serde(crate = "lyquor_primitives::serde")]
332 struct parameters { $($var:$type),* }
333 $crate::decode_object::<parameters>($encoded)
334 }};
335}
336
337#[derive(Serialize, Deserialize, Debug)]
338pub struct Range<T> {
339 pub start: Option<T>,
340 pub end: Option<T>,
341}
342
343#[macro_export]
344macro_rules! debug_struct_name {
345 ($t:ty) => {
346 impl std::fmt::Debug for $t {
347 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
348 f.write_str(stringify!($t))
349 }
350 }
351 };
352}
353
354#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug)]
356pub enum Cipher {
357 Ed25519,
358 Secp256k1,
359}