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, SequenceBackendID, sequence_backend_id};
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)]
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 block_index(&self) -> u32 {
69 self.0 as u32
70 }
71
72 #[inline(always)]
73 pub fn next_block(&self) -> Self {
74 Self(((self.0 >> 32) + 1) << 32)
75 }
76}
77
78impl fmt::Display for ChainPos {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
80 write!(f, "(block={}, log={})", self.0 >> 32, self.0 as u32)
81 }
82}
83
84impl fmt::Debug for ChainPos {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
86 fmt::Display::fmt(self, f)
87 }
88}
89
90#[derive(Serialize, Deserialize)]
91#[serde(rename_all = "camelCase")]
92struct HumanReadableChainPos {
93 block_number: U64,
94 block_index: U32,
95}
96
97impl Serialize for ChainPos {
98 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
99 where
100 S: serde::Serializer,
101 {
102 if serializer.is_human_readable() {
103 HumanReadableChainPos {
104 block_number: U64::from(self.block()),
105 block_index: U32::from(self.block_index()),
106 }
107 .serialize(serializer)
108 } else {
109 serializer.serialize_u128(self.0)
110 }
111 }
112}
113
114impl<'de> Deserialize<'de> for ChainPos {
115 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
116 where
117 D: serde::Deserializer<'de>,
118 {
119 if deserializer.is_human_readable() {
120 let HumanReadableChainPos {
121 block_number,
122 block_index,
123 } = HumanReadableChainPos::deserialize(deserializer)?;
124 Ok(Self::new(block_number.to::<u64>(), block_index.to::<u32>()))
125 } else {
126 Ok(Self(u128::deserialize(deserializer)?))
127 }
128 }
129}
130
131#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug)]
132pub enum InputABI {
133 Lyquor,
134 Eth,
135}
136
137#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
138pub enum TriggerMode {
139 Recurrent(u64),
141 Once(u64),
143 Sync,
145 Stop,
147}
148
149#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
150pub struct HashBytes(Hash);
151
152impl HashBytes {
153 pub fn new(hash: Hash) -> Self {
154 Self(hash)
155 }
156
157 pub fn into_inner(self) -> Hash {
158 self.0
159 }
160}
161
162impl std::ops::Deref for HashBytes {
163 type Target = Hash;
164 fn deref(&self) -> &Hash {
165 &self.0
166 }
167}
168
169impl From<[u8; 32]> for HashBytes {
170 fn from(hash: [u8; 32]) -> Self {
171 Self(hash.into())
172 }
173}
174
175impl From<HashBytes> for [u8; 32] {
176 fn from(hash: HashBytes) -> Self {
177 hash.0.into()
178 }
179}
180
181impl From<Hash> for HashBytes {
182 fn from(hash: Hash) -> Self {
183 Self(hash)
184 }
185}
186
187impl From<HashBytes> for Hash {
188 fn from(hash_bytes: HashBytes) -> Self {
189 hash_bytes.0
190 }
191}
192
193impl Serialize for HashBytes {
194 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195 where
196 S: serde::Serializer,
197 {
198 let bytes: &[u8; 32] = self.0.as_bytes();
199 serializer.serialize_bytes(bytes)
200 }
201}
202
203impl<'de> Deserialize<'de> for HashBytes {
204 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
205 where
206 D: serde::Deserializer<'de>,
207 {
208 use serde::de::Error;
209 let bytes = <Vec<u8>>::deserialize(deserializer)?;
210 if bytes.len() != 32 {
211 return Err(D::Error::custom(format!(
212 "Expected 32 bytes for HashBytes, got {}",
213 bytes.len()
214 )));
215 }
216 let mut array = [0u8; 32];
217 array.copy_from_slice(&bytes);
218 Ok(HashBytes(blake3::Hash::from(array)))
219 }
220}
221
222#[derive(Serialize, Deserialize, PartialEq, Clone, TypedBuilder)]
223pub struct CallParams {
224 #[builder(default = Address::ZERO)]
227 pub origin: Address,
228 pub caller: Address,
230 #[builder(default = GROUP_DEFAULT.into())]
231 pub group: String,
232 pub method: String,
233 pub input: Bytes,
234 #[builder(default = InputABI::Lyquor)]
235 pub abi: InputABI,
236}
237
238impl Eq for CallParams {}
239
240impl fmt::Debug for CallParams {
241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
242 write!(
243 f,
244 "CallParams(caller={}, origin={}, group={}, method={}, input={}, abi={:?})",
245 self.caller,
246 self.origin,
247 self.group,
248 self.method,
249 hex::encode(&self.input),
250 self.abi
251 )
252 }
253}
254
255pub const GROUP_DEFAULT: &str = "main";
256pub const GROUP_NODE: &str = "node";
257pub const GROUP_UPC_PREPARE: &str = "upc::prepare";
258pub const GROUP_UPC_REQ: &str = "upc::request";
259pub const GROUP_UPC_RESP: &str = "upc::response";
260
261pub type LyteLogTopic = B256;
262
263#[derive(Serialize, Deserialize, Clone)]
264pub struct LyteLog {
265 pub topics: [Option<Box<LyteLogTopic>>; 4],
266 pub data: Bytes,
267}
268
269impl LyteLog {
270 pub fn new_from_tagged_value<V: Serialize>(tag: &str, value: &V) -> Self {
271 let topic0 = Box::new(Self::tagged_value_topic(tag));
272 Self {
273 topics: [Some(topic0), None, None, None],
274 data: encode_object(value).into(),
275 }
276 }
277
278 pub fn tagged_value_topic(tag: &str) -> LyteLogTopic {
279 let mut hasher = blake3::Hasher::new();
280 hasher.update(tag.as_bytes());
281 let topic: [u8; 32] = hasher.finalize().into();
282 topic.into()
283 }
284}
285
286#[derive(Serialize, Deserialize, Clone, Debug)]
287pub struct RegisterEvent {
288 pub id: LyquidID,
289 pub deps: Vec<LyquidID>,
290}
291
292impl fmt::Debug for LyteLog {
293 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
294 write!(
295 f,
296 "LyteLog(topics={}, data=<{} bytes>)",
297 self.topics
298 .iter()
299 .map(|t| match t {
300 Some(t) => t.to_string(),
301 None => "_".into(),
302 })
303 .collect::<Vec<_>>()
304 .join(", "),
305 self.data.len()
306 )
307 }
308}
309
310pub fn decode_object<T: for<'a> Deserialize<'a>>(raw: &[u8]) -> Option<T> {
311 postcard::from_bytes(raw).ok()
312}
313
314pub fn encode_object<T: Serialize + ?Sized>(obj: &T) -> Vec<u8> {
315 postcard::to_stdvec(obj).expect("postcard serialization failed")
316}
317
318pub fn encode_object_with_prefix<T: Serialize + ?Sized>(prefix: &[u8], obj: &T) -> Vec<u8> {
319 let mut vec = Vec::with_capacity(prefix.len() + core::mem::size_of_val(obj));
320 vec.extend_from_slice(prefix);
321 postcard::to_io(obj, &mut vec).expect("postcard serialization failed");
322 vec
323}
324
325#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)]
326pub enum StateCategory {
327 Network,
328 Instance,
329}
330
331impl StateCategory {
332 pub fn as_runtime(&self) -> u8 {
333 match self {
334 Self::Instance => 0x1,
335 Self::Network => 0x2,
336 }
337 }
338}
339
340#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Copy, Clone)]
341#[serde(rename_all = "camelCase")]
342pub enum ConsoleSink {
343 StdOut,
344 StdErr,
345}
346
347pub fn encode_method_name(cat_prefix: &str, group: &str, method: &str) -> String {
348 let mut output = cat_prefix.to_string();
349 output.push('_');
350 cb58::bs58::encode(group.as_bytes()).onto(&mut output).unwrap();
351 output.push('_');
352 output.push_str(method);
353 output
354}
355
356#[doc(hidden)]
357#[macro_export]
358macro_rules! object_by_fields_ {
359 ($serde_crate: tt, $($var:ident: $type:ty = $val:expr),*) => {{
360 #[allow(non_camel_case_types)]
361 #[derive($crate::Serialize, Clone)]
362 #[serde(crate = $serde_crate)]
363 struct parameters { $($var:$type),* }
364 parameters { $($var: $val),* }
365 }};
366}
367
368#[macro_export]
369macro_rules! object_by_fields {
370 ($($token: tt)*) => {{
371 $crate::object_by_fields_!("lyquor_primitives::serde", $($token)*)
372 }};
373}
374
375#[doc(hidden)]
376#[macro_export]
377macro_rules! encode_by_fields_ {
378 ($serde_crate: tt, $($var:ident: $type:ty = $val:expr),*) => {{
379 $crate::encode_object(&$crate::object_by_fields_!($serde_crate, $($var: $type = $val),*))
380 }};
381 ($serde_crate: tt, $($var:ident: $type:ty),*) => {{
382 $crate::encode_object(&$crate::object_by_fields_!($serde_crate, $($var: $type = $var),*))
383 }};
384}
385
386#[macro_export]
387macro_rules! encode_by_fields {
388 ($($token: tt)*) => {{
389 $crate::encode_by_fields_!("lyquor_primitives::serde", $($token)*)
390 }};
391}
392
393#[macro_export]
394macro_rules! decode_by_fields {
395 ($encoded:expr, $($var:ident: $type:ty),*) => {{
396 #[allow(non_camel_case_types)]
397 #[derive($crate::Deserialize)]
398 #[serde(crate = "lyquor_primitives::serde")]
399 struct parameters { $($var:$type),* }
400 $crate::decode_object::<parameters>($encoded)
401 }};
402}
403
404#[derive(Serialize, Deserialize, Debug)]
405pub struct Range<T> {
406 pub start: Option<T>,
407 pub end: Option<T>,
408}
409
410#[macro_export]
411macro_rules! debug_struct_name {
412 ($t:ty) => {
413 impl std::fmt::Debug for $t {
414 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
415 f.write_str(stringify!($t))
416 }
417 }
418 };
419}
420
421#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Debug)]
423pub enum Cipher {
424 Ed25519,
425 Secp256k1,
426}