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}