eventify_primitives/
networks.rs

1pub mod arbitrum;
2pub mod avalanche;
3pub mod base;
4pub mod bsc;
5pub mod core;
6pub mod ethereum;
7pub mod linea;
8pub mod optimism;
9pub mod polygon;
10pub mod zksync;
11
12use alloy_primitives::B256;
13use sqlx::{Error as SqlError, PgPool};
14
15use crate::{
16    events::{ERC1155, ERC20, ERC4626, ERC721, ERC777},
17    BlockT, EmitT, InsertT, LogT, PropagateError, StreamT,
18};
19
20#[derive(Clone, Debug)]
21pub struct NetworkKindError(String);
22impl std::error::Error for NetworkKindError {}
23impl std::fmt::Display for NetworkKindError {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        write!(f, "invalid network: {}", self.0)
26    }
27}
28
29#[derive(
30    Clone,
31    Copy,
32    Debug,
33    Default,
34    PartialEq,
35    Eq,
36    Hash,
37    serde::Serialize,
38    serde::Deserialize,
39    sqlx::Type,
40    utoipa::ToSchema,
41)]
42#[serde(rename_all = "lowercase")]
43#[sqlx(type_name = "network_type", rename_all = "lowercase")]
44pub enum NetworkKind {
45    #[serde(alias = "eth")]
46    #[default]
47    Ethereum,
48    Zksync,
49    #[serde(alias = "polygon_pos")]
50    Polygon,
51    Optimism,
52    Arbitrum,
53    Linea,
54    Avalanche,
55    #[serde(alias = "binance-smart-chain")]
56    Bsc,
57    Base,
58}
59
60impl std::fmt::Display for NetworkKind {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        match self {
63            NetworkKind::Ethereum => write!(f, "ethereum"),
64            NetworkKind::Zksync => write!(f, "zksync"),
65            NetworkKind::Polygon => write!(f, "polygon"),
66            NetworkKind::Optimism => write!(f, "optimism"),
67            NetworkKind::Arbitrum => write!(f, "arbitrum"),
68            NetworkKind::Linea => write!(f, "linea"),
69            NetworkKind::Avalanche => write!(f, "avalanche"),
70            NetworkKind::Bsc => write!(f, "bsc"),
71            NetworkKind::Base => write!(f, "base"),
72        }
73    }
74}
75
76impl std::str::FromStr for NetworkKind {
77    type Err = NetworkKindError;
78
79    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
80        match s.to_lowercase().as_str() {
81            "ethereum" | "eth" => Ok(NetworkKind::Ethereum),
82            "zksync" => Ok(NetworkKind::Zksync),
83            "polygon" => Ok(NetworkKind::Polygon),
84            "optimism" => Ok(NetworkKind::Optimism),
85            "arbitrum" => Ok(NetworkKind::Arbitrum),
86            "linea" => Ok(NetworkKind::Linea),
87            "avalanche" => Ok(NetworkKind::Avalanche),
88            "bsc" => Ok(NetworkKind::Bsc),
89            "base" => Ok(NetworkKind::Base),
90            _ => Err(NetworkKindError(s.to_string())),
91        }
92    }
93}
94
95#[allow(non_camel_case_types)]
96#[derive(Debug, Clone, serde::Serialize)]
97pub enum Logs<L: LogT> {
98    Raw(L),
99
100    ERC20_Transfer(ERC20::Transfer),
101    ERC20_Approval(ERC20::Approval),
102
103    ERC721_Transfer(ERC721::Transfer),
104    ERC721_Approval(ERC721::Approval),
105    ERC721_ApprovalForAll(ERC721::ApprovalForAll),
106
107    ERC777_Sent(ERC777::Sent),
108    ERC777_Minted(ERC777::Minted),
109    ERC777_Burned(ERC777::Burned),
110    ERC777_AuthorizedOperator(ERC777::AuthorizedOperator),
111    ERC777_RevokedOperator(ERC777::RevokedOperator),
112
113    ERC1155_TransferSingle(ERC1155::TransferSingle),
114    ERC1155_TransferBatch(ERC1155::TransferBatch),
115    ERC1155_URI(ERC1155::URI),
116
117    ERC4626_Deposit(ERC4626::Deposit),
118    ERC4626_Withdraw(ERC4626::Withdraw),
119}
120
121impl<L: LogT> std::fmt::Display for Logs<L> {
122    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123        match self {
124            Logs::Raw(_) => write!(f, "log"),
125            Logs::ERC20_Transfer(_) => write!(f, "log_erc20_transfer"),
126            Logs::ERC20_Approval(_) => write!(f, "log_erc20_approval"),
127
128            Logs::ERC721_Transfer(_) => write!(f, "log_erc721_transfer"),
129            Logs::ERC721_Approval(_) => write!(f, "log_erc721_approval"),
130            Logs::ERC721_ApprovalForAll(_) => write!(f, "log_erc721_approval_for_all"),
131
132            Logs::ERC777_Sent(_) => write!(f, "log_erc777_sent"),
133            Logs::ERC777_Minted(_) => write!(f, "log_erc777_minted"),
134            Logs::ERC777_Burned(_) => write!(f, "log_erc777_burned"),
135            Logs::ERC777_AuthorizedOperator(_) => write!(f, "log_erc777_authorized_operator"),
136            Logs::ERC777_RevokedOperator(_) => write!(f, "log_erc777_revoked_operator"),
137
138            Logs::ERC1155_TransferSingle(_) => write!(f, "log_erc1155_transfer_single"),
139            Logs::ERC1155_TransferBatch(_) => write!(f, "log_erc1155_transfer_batch"),
140            Logs::ERC1155_URI(_) => write!(f, "log_erc1155_uri"),
141
142            Logs::ERC4626_Deposit(_) => write!(f, "log_erc4626_deposit"),
143            Logs::ERC4626_Withdraw(_) => write!(f, "log_erc4626_withdraw"),
144        }
145    }
146}
147
148impl<L: LogT> InsertT for Logs<L> {
149    async fn insert(&self, pool: &PgPool, tx_hash: &Option<B256>) -> eyre::Result<(), SqlError> {
150        match self {
151            Logs::Raw(log) => log.insert(pool, tx_hash).await?,
152            Logs::ERC20_Transfer(e) => e.insert(pool, tx_hash).await?,
153            Logs::ERC20_Approval(e) => e.insert(pool, tx_hash).await?,
154
155            Logs::ERC721_Transfer(e) => e.insert(pool, tx_hash).await?,
156            Logs::ERC721_Approval(e) => e.insert(pool, tx_hash).await?,
157            Logs::ERC721_ApprovalForAll(e) => e.insert(pool, tx_hash).await?,
158
159            Logs::ERC777_Sent(e) => e.insert(pool, tx_hash).await?,
160            Logs::ERC777_Minted(e) => e.insert(pool, tx_hash).await?,
161            Logs::ERC777_Burned(e) => e.insert(pool, tx_hash).await?,
162            Logs::ERC777_AuthorizedOperator(e) => e.insert(pool, tx_hash).await?,
163            Logs::ERC777_RevokedOperator(e) => e.insert(pool, tx_hash).await?,
164
165            Logs::ERC1155_TransferSingle(e) => e.insert(pool, tx_hash).await?,
166            Logs::ERC1155_TransferBatch(e) => e.insert(pool, tx_hash).await?,
167            Logs::ERC1155_URI(e) => e.insert(pool, tx_hash).await?,
168
169            Logs::ERC4626_Deposit(e) => e.insert(pool, tx_hash).await?,
170            Logs::ERC4626_Withdraw(e) => e.insert(pool, tx_hash).await?,
171        }
172
173        Ok(())
174    }
175}
176
177impl<L: LogT + serde::Serialize> EmitT for Logs<L> {
178    async fn emit(
179        &self,
180        queue: &redis::Client,
181        network: &crate::networks::NetworkKind,
182    ) -> eyre::Result<(), PropagateError> {
183        match self {
184            Logs::Raw(log) => log.emit(queue, network).await?,
185            Logs::ERC20_Transfer(e) => e.emit(queue, network).await?,
186            Logs::ERC20_Approval(e) => e.emit(queue, network).await?,
187
188            Logs::ERC721_Transfer(e) => e.emit(queue, network).await?,
189            Logs::ERC721_Approval(e) => e.emit(queue, network).await?,
190            Logs::ERC721_ApprovalForAll(e) => e.emit(queue, network).await?,
191
192            Logs::ERC777_Sent(e) => e.emit(queue, network).await?,
193            Logs::ERC777_Minted(e) => e.emit(queue, network).await?,
194            Logs::ERC777_Burned(e) => e.emit(queue, network).await?,
195            Logs::ERC777_AuthorizedOperator(e) => e.emit(queue, network).await?,
196            Logs::ERC777_RevokedOperator(e) => e.emit(queue, network).await?,
197
198            Logs::ERC1155_TransferSingle(e) => e.emit(queue, network).await?,
199            Logs::ERC1155_TransferBatch(e) => e.emit(queue, network).await?,
200            Logs::ERC1155_URI(e) => e.emit(queue, network).await?,
201
202            Logs::ERC4626_Deposit(e) => e.emit(queue, network).await?,
203            Logs::ERC4626_Withdraw(e) => e.emit(queue, network).await?,
204        }
205
206        Ok(())
207    }
208}
209
210impl<L: LogT + serde::Serialize> StreamT for Logs<L> {
211    async fn stream(
212        &self,
213        queue: &redis::Client,
214        network: &crate::networks::NetworkKind,
215    ) -> eyre::Result<(), PropagateError> {
216        match self {
217            Logs::Raw(log) => log.stream(queue, network).await?,
218            Logs::ERC20_Transfer(e) => e.stream(queue, network).await?,
219            Logs::ERC20_Approval(e) => e.stream(queue, network).await?,
220
221            Logs::ERC721_Transfer(e) => e.stream(queue, network).await?,
222            Logs::ERC721_Approval(e) => e.stream(queue, network).await?,
223            Logs::ERC721_ApprovalForAll(e) => e.stream(queue, network).await?,
224
225            Logs::ERC777_Sent(e) => e.stream(queue, network).await?,
226            Logs::ERC777_Minted(e) => e.stream(queue, network).await?,
227            Logs::ERC777_Burned(e) => e.stream(queue, network).await?,
228            Logs::ERC777_AuthorizedOperator(e) => e.stream(queue, network).await?,
229            Logs::ERC777_RevokedOperator(e) => e.stream(queue, network).await?,
230
231            Logs::ERC1155_TransferSingle(e) => e.stream(queue, network).await?,
232            Logs::ERC1155_TransferBatch(e) => e.stream(queue, network).await?,
233            Logs::ERC1155_URI(e) => e.stream(queue, network).await?,
234
235            Logs::ERC4626_Deposit(e) => e.stream(queue, network).await?,
236            Logs::ERC4626_Withdraw(e) => e.stream(queue, network).await?,
237        }
238
239        Ok(())
240    }
241}
242
243#[derive(Debug, Clone, serde::Serialize)]
244pub enum Resource<B, L>
245where
246    B: BlockT,
247    L: LogT,
248{
249    Block(B),
250    Log(Logs<L>),
251}
252
253impl<B, L> InsertT for Resource<B, L>
254where
255    B: BlockT,
256    L: LogT,
257{
258    async fn insert(&self, pool: &PgPool, tx_hash: &Option<B256>) -> eyre::Result<(), SqlError> {
259        match self {
260            Resource::Block(block) => block.insert(pool, tx_hash).await?,
261            Resource::Log(log) => log.insert(pool, tx_hash).await?,
262        }
263
264        Ok(())
265    }
266}
267
268impl<B, L> EmitT for Resource<B, L>
269where
270    B: BlockT,
271    L: LogT,
272{
273    async fn emit(
274        &self,
275        queue: &redis::Client,
276        network: &crate::networks::NetworkKind,
277    ) -> eyre::Result<(), PropagateError> {
278        match self {
279            Resource::Block(block) => block.emit(queue, network).await?,
280            Resource::Log(log) => log.emit(queue, network).await?,
281        }
282
283        Ok(())
284    }
285}
286
287impl<B, L> StreamT for Resource<B, L>
288where
289    B: BlockT,
290    L: LogT,
291{
292    async fn stream(
293        &self,
294        queue: &redis::Client,
295        network: &crate::networks::NetworkKind,
296    ) -> eyre::Result<(), PropagateError> {
297        match self {
298            Resource::Block(block) => block.stream(queue, network).await?,
299            Resource::Log(log) => log.stream(queue, network).await?,
300        }
301
302        Ok(())
303    }
304}
305
306#[derive(
307    Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, utoipa::ToSchema,
308)]
309#[serde(rename_all = "lowercase")]
310pub enum ResourceKind {
311    Block,
312    Log(LogKind),
313}
314
315impl ResourceKind {
316    pub fn resources_from_string(s: String) -> std::collections::HashSet<ResourceKind> {
317        s.split(',')
318            .map(|x| match x.trim().to_lowercase().as_str() {
319                "block" | "blocks" => ResourceKind::Block,
320                "log" | "logs" => ResourceKind::Log(LogKind::Raw),
321                _ => {
322                    panic!("invalid resource: {}", x);
323                }
324            })
325            .collect()
326    }
327
328    pub fn resources_from_str(s: &str) -> std::collections::HashSet<ResourceKind> {
329        ResourceKind::resources_from_string(s.to_string())
330    }
331}
332
333impl std::fmt::Display for ResourceKind {
334    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
335        match self {
336            ResourceKind::Block => write!(f, "block"),
337            ResourceKind::Log(kind) => write!(f, "{}", kind),
338        }
339    }
340}
341
342#[allow(non_camel_case_types)]
343#[derive(
344    Clone,
345    Copy,
346    Debug,
347    Default,
348    PartialEq,
349    Eq,
350    Hash,
351    serde::Serialize,
352    serde::Deserialize,
353    sqlx::Type,
354    utoipa::ToSchema,
355)]
356#[serde(rename_all = "lowercase")]
357pub enum LogKind {
358    #[default]
359    Raw,
360
361    ERC20_Transfer,
362    ERC20_Approval,
363
364    ERC721_Transfer,
365    ERC721_Approval,
366    ERC721_ApprovalForAll,
367
368    ERC777_Sent,
369    ERC777_Minted,
370    ERC777_Burned,
371    ERC777_AuthorizedOperator,
372    ERC777_RevokedOperator,
373
374    ERC1155_TransferSingle,
375    ERC1155_TransferBatch,
376    ERC1155_URI,
377
378    ERC4626_Deposit,
379    ERC4626_Withdraw,
380}
381
382impl std::fmt::Display for LogKind {
383    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
384        match self {
385            LogKind::Raw => write!(f, "log"),
386            LogKind::ERC20_Transfer => write!(f, "log_erc20_transfer"),
387            LogKind::ERC20_Approval => write!(f, "log_erc20_approval"),
388
389            LogKind::ERC721_Transfer => write!(f, "log_erc721_transfer"),
390            LogKind::ERC721_Approval => write!(f, "log_erc721_approval"),
391            LogKind::ERC721_ApprovalForAll => write!(f, "log_erc721_approval_for_all"),
392
393            LogKind::ERC777_Sent => write!(f, "log_erc777_sent"),
394            LogKind::ERC777_Minted => write!(f, "log_erc777_minted"),
395            LogKind::ERC777_Burned => write!(f, "log_erc777_burned"),
396            LogKind::ERC777_AuthorizedOperator => write!(f, "log_erc777_authorized_operator"),
397            LogKind::ERC777_RevokedOperator => write!(f, "log_erc777_revoked_operator"),
398
399            LogKind::ERC1155_TransferSingle => write!(f, "log_erc1155_transfer_single"),
400            LogKind::ERC1155_TransferBatch => write!(f, "log_erc1155_transfer_batch"),
401            LogKind::ERC1155_URI => write!(f, "log_erc1155_uri"),
402
403            LogKind::ERC4626_Deposit => write!(f, "log_erc4626_deposit"),
404            LogKind::ERC4626_Withdraw => write!(f, "log_erc4626_withdraw"),
405        }
406    }
407}