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