use crate::chain::ChainId;
use crate::types::NormalizedValue;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RawEvent {
pub chain: ChainId,
pub tx_hash: String,
pub block_number: u64,
pub block_timestamp: i64,
pub log_index: u32,
pub topics: Vec<String>,
pub data: Vec<u8>,
pub address: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub raw_receipt: Option<serde_json::Value>,
}
impl RawEvent {
pub fn evm_event_signature(&self) -> Option<&str> {
self.topics.first().map(|s| s.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct EventFingerprint(pub String);
impl EventFingerprint {
pub fn new(hex: impl Into<String>) -> Self {
Self(hex.into())
}
pub fn as_hex(&self) -> &str {
&self.0
}
}
impl std::fmt::Display for EventFingerprint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DecodedEvent {
pub chain: ChainId,
pub schema: String,
pub schema_version: u32,
pub tx_hash: String,
pub block_number: u64,
pub block_timestamp: i64,
pub log_index: u32,
pub address: String,
pub fields: HashMap<String, NormalizedValue>,
pub fingerprint: EventFingerprint,
#[serde(skip_serializing_if = "HashMap::is_empty", default)]
pub decode_errors: HashMap<String, String>,
}
impl DecodedEvent {
pub fn field(&self, name: &str) -> Option<&NormalizedValue> {
self.fields.get(name)
}
pub fn has_errors(&self) -> bool {
!self.decode_errors.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::chain::chains;
fn sample_raw() -> RawEvent {
RawEvent {
chain: chains::ethereum(),
tx_hash: "0xabc123".into(),
block_number: 19_000_000,
block_timestamp: 1_700_000_000,
log_index: 2,
topics: vec![
"0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67".into(),
],
data: vec![0u8; 32],
address: "0xe0554a476a092703abdb3ef35c80e0d76d32939f".into(),
raw_receipt: None,
}
}
#[test]
fn raw_event_evm_signature() {
let e = sample_raw();
assert!(e.evm_event_signature().unwrap().starts_with("0xc42079"));
}
}