1pub mod blockchain;
2pub mod contract;
3pub mod error;
4pub mod protocol;
5pub mod token;
6
7use std::{collections::HashMap, fmt::Display, str::FromStr};
8
9use deepsize::DeepSizeOf;
10use serde::{Deserialize, Serialize};
11use strum_macros::{Display, EnumString};
12use thiserror::Error;
13use token::Token;
14
15use crate::{dto, Bytes};
16
17pub type Address = Bytes;
20
21pub type BlockHash = Bytes;
24
25pub type TxHash = Bytes;
28
29pub type Code = Bytes;
31
32pub type CodeHash = Bytes;
34
35pub type Balance = Bytes;
37
38pub type StoreKey = Bytes;
40
41pub type AttrStoreKey = String;
43
44pub type StoreVal = Bytes;
46
47pub type ContractStore = HashMap<StoreKey, StoreVal>;
49pub type ContractStoreDeltas = HashMap<StoreKey, Option<StoreVal>>;
50pub type AccountToContractStoreDeltas = HashMap<Address, ContractStoreDeltas>;
51
52pub type ComponentId = String;
54
55pub type ProtocolSystem = String;
57
58pub type EntryPointId = String;
60
61#[derive(
62 Debug,
63 Clone,
64 Copy,
65 PartialEq,
66 Eq,
67 Hash,
68 Serialize,
69 Deserialize,
70 EnumString,
71 Display,
72 Default,
73 DeepSizeOf,
74)]
75#[serde(rename_all = "lowercase")]
76#[strum(serialize_all = "lowercase")]
77pub enum Chain {
78 #[default]
79 Ethereum,
80 Starknet,
81 ZkSync,
82 Arbitrum,
83 Base,
84 Bsc,
85 Unichain,
86}
87
88impl From<dto::Chain> for Chain {
89 fn from(value: dto::Chain) -> Self {
90 match value {
91 dto::Chain::Ethereum => Chain::Ethereum,
92 dto::Chain::Starknet => Chain::Starknet,
93 dto::Chain::ZkSync => Chain::ZkSync,
94 dto::Chain::Arbitrum => Chain::Arbitrum,
95 dto::Chain::Base => Chain::Base,
96 dto::Chain::Bsc => Chain::Bsc,
97 dto::Chain::Unichain => Chain::Unichain,
98 }
99 }
100}
101
102fn native_eth(chain: Chain) -> Token {
103 Token::new(
104 &Bytes::from_str("0x0000000000000000000000000000000000000000").unwrap(),
105 "ETH",
106 18,
107 0,
108 &[Some(2300)],
109 chain,
110 100,
111 )
112}
113
114fn native_bsc(chain: Chain) -> Token {
115 Token::new(
116 &Bytes::from_str("0x0000000000000000000000000000000000000000").unwrap(),
117 "BNB",
118 18,
119 0,
120 &[Some(2300)],
121 chain,
122 100,
123 )
124}
125
126fn wrapped_native_eth(chain: Chain, address: &str) -> Token {
127 Token::new(&Bytes::from_str(address).unwrap(), "WETH", 18, 0, &[Some(2300)], chain, 100)
128}
129
130fn wrapped_native_bsc(chain: Chain, address: &str) -> Token {
131 Token::new(&Bytes::from_str(address).unwrap(), "WBNB", 18, 0, &[Some(2300)], chain, 100)
132}
133
134impl Chain {
135 pub fn id(&self) -> u64 {
136 match self {
137 Chain::Ethereum => 1,
138 Chain::ZkSync => 324,
139 Chain::Arbitrum => 42161,
140 Chain::Starknet => 0,
141 Chain::Base => 8453,
142 Chain::Bsc => 56,
143 Chain::Unichain => 130,
144 }
145 }
146
147 pub fn native_token(&self) -> Token {
149 match self {
150 Chain::Ethereum => native_eth(Chain::Ethereum),
151 Chain::Starknet => native_eth(Chain::Starknet),
154 Chain::ZkSync => native_eth(Chain::ZkSync),
155 Chain::Arbitrum => native_eth(Chain::Arbitrum),
156 Chain::Base => native_eth(Chain::Base),
157 Chain::Bsc => native_bsc(Chain::Bsc),
158 Chain::Unichain => native_eth(Chain::Unichain),
159 }
160 }
161
162 pub fn wrapped_native_token(&self) -> Token {
164 match self {
165 Chain::Ethereum => {
166 wrapped_native_eth(Chain::Ethereum, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
167 }
168 Chain::Starknet => {
170 wrapped_native_eth(Chain::Starknet, "0x0000000000000000000000000000000000000000")
171 }
172 Chain::ZkSync => {
173 wrapped_native_eth(Chain::ZkSync, "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91")
174 }
175 Chain::Arbitrum => {
176 wrapped_native_eth(Chain::Arbitrum, "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1")
177 }
178 Chain::Base => {
179 wrapped_native_eth(Chain::Base, "0x4200000000000000000000000000000000000006")
180 }
181 Chain::Bsc => {
182 wrapped_native_bsc(Chain::Bsc, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c")
183 }
184 Chain::Unichain => {
185 wrapped_native_eth(Chain::Unichain, "0x4200000000000000000000000000000000000006")
186 }
187 }
188 }
189}
190
191#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, Default)]
192pub struct ExtractorIdentity {
193 pub chain: Chain,
194 pub name: String,
195}
196
197impl ExtractorIdentity {
198 pub fn new(chain: Chain, name: &str) -> Self {
199 Self { chain, name: name.to_owned() }
200 }
201}
202
203impl std::fmt::Display for ExtractorIdentity {
204 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205 write!(f, "{}:{}", self.chain, self.name)
206 }
207}
208
209impl From<ExtractorIdentity> for dto::ExtractorIdentity {
210 fn from(value: ExtractorIdentity) -> Self {
211 dto::ExtractorIdentity { chain: value.chain.into(), name: value.name }
212 }
213}
214
215impl From<dto::ExtractorIdentity> for ExtractorIdentity {
216 fn from(value: dto::ExtractorIdentity) -> Self {
217 Self { chain: value.chain.into(), name: value.name }
218 }
219}
220
221#[derive(Debug, PartialEq, Clone)]
222pub struct ExtractionState {
223 pub name: String,
224 pub chain: Chain,
225 pub attributes: serde_json::Value,
226 pub cursor: Vec<u8>,
227 pub block_hash: Bytes,
228}
229
230impl ExtractionState {
231 pub fn new(
232 name: String,
233 chain: Chain,
234 attributes: Option<serde_json::Value>,
235 cursor: &[u8],
236 block_hash: Bytes,
237 ) -> Self {
238 ExtractionState {
239 name,
240 chain,
241 attributes: attributes.unwrap_or_default(),
242 cursor: cursor.to_vec(),
243 block_hash,
244 }
245 }
246}
247
248#[derive(PartialEq, Debug, Clone, Default, Deserialize, Serialize)]
249pub enum ImplementationType {
250 #[default]
251 Vm,
252 Custom,
253}
254
255#[derive(PartialEq, Debug, Clone, Default, Deserialize, Serialize)]
256pub enum FinancialType {
257 #[default]
258 Swap,
259 Psm,
260 Debt,
261 Leverage,
262}
263
264#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
265pub struct ProtocolType {
266 pub name: String,
267 pub financial_type: FinancialType,
268 pub attribute_schema: Option<serde_json::Value>,
269 pub implementation: ImplementationType,
270}
271
272impl ProtocolType {
273 pub fn new(
274 name: String,
275 financial_type: FinancialType,
276 attribute_schema: Option<serde_json::Value>,
277 implementation: ImplementationType,
278 ) -> Self {
279 ProtocolType { name, financial_type, attribute_schema, implementation }
280 }
281}
282
283#[derive(Debug, PartialEq, Default, Copy, Clone, Deserialize, Serialize, DeepSizeOf)]
284pub enum ChangeType {
285 #[default]
286 Update,
287 Deletion,
288 Creation,
289}
290
291#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
292pub struct ContractId {
293 pub address: Address,
294 pub chain: Chain,
295}
296
297impl ContractId {
299 pub fn new(chain: Chain, address: Address) -> Self {
300 Self { address, chain }
301 }
302
303 pub fn address(&self) -> &Address {
304 &self.address
305 }
306}
307
308impl Display for ContractId {
309 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
310 write!(f, "{:?}: 0x{}", self.chain, hex::encode(&self.address))
311 }
312}
313
314#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
315pub struct PaginationParams {
316 pub page: i64,
317 pub page_size: i64,
318}
319
320impl PaginationParams {
321 pub fn new(page: i64, page_size: i64) -> Self {
322 Self { page, page_size }
323 }
324
325 pub fn offset(&self) -> i64 {
326 self.page * self.page_size
327 }
328}
329
330impl From<&dto::PaginationParams> for PaginationParams {
331 fn from(value: &dto::PaginationParams) -> Self {
332 PaginationParams { page: value.page, page_size: value.page_size }
333 }
334}
335
336#[derive(Error, Debug, PartialEq)]
337pub enum MergeError {
338 #[error("Can't merge {0} from differring idendities: Expected {1}, got {2}")]
339 IdMismatch(String, String, String),
340 #[error("Can't merge {0} from different blocks: 0x{1:x} != 0x{2:x}")]
341 BlockMismatch(String, Bytes, Bytes),
342 #[error("Can't merge {0} from the same transaction: 0x{1:x}")]
343 SameTransaction(String, Bytes),
344 #[error("Can't merge {0} with lower transaction index: {1} > {2}")]
345 TransactionOrderError(String, u64, u64),
346}