ccnext_query_builder/abi/
query_builder_for_event.rs1use alloy::{
2 dyn_abi::{DecodedEvent, Specifier},
3 rpc::types::Log,
4};
5use alloy_json_abi::Event;
6
7use super::{
8 models::{FieldMetadata, QueryBuilderError},
9 utils::compute_abi_offsets,
10};
11
12pub struct QueryBuilderForEvent {
13 field: FieldMetadata,
14 log: Log,
15 _decoded_event: DecodedEvent,
16 event: Event,
17 selected_offsets: Vec<(usize, usize)>,
18}
19
20impl QueryBuilderForEvent {
21 pub(crate) fn new(
22 log_field: FieldMetadata,
23 log: Log,
24 _decoded_event: DecodedEvent,
25 event: Event,
26 ) -> Self {
27 Self {
28 field: log_field,
29 log,
30 _decoded_event,
31 event,
32 selected_offsets: vec![],
33 }
34 }
35
36 pub fn add_argument(&mut self, name: &str) -> Result<&mut Self, QueryBuilderError> {
37 let mut topic_index: usize = 0;
38 let mut data_index: usize = 0;
39
40 for event_input in self.event.inputs.clone() {
41 if event_input.indexed {
44 topic_index += 1;
45 }
46
47 if event_input.name == name {
48 if event_input.indexed {
49 match self.field.children.get(1) {
52 Some(topics) => {
54 match topics.children.get(topic_index) {
55 Some(subject_topic) => {
56 self.selected_offsets.push((subject_topic.offset, 32));
60 return Ok(self);
61 }
62 None => {
63 return Err(QueryBuilderError::MissingDataInAbiOffsets);
64 }
65 }
66 }
67 None => {
68 return Err(QueryBuilderError::MissingDataInAbiOffsets);
69 }
70 }
71 } else {
72 let data_field = match self.field.children.get(2) {
74 Some(df) => df,
75 None => {
76 return Err(QueryBuilderError::MissingDataInAbiOffsets);
77 }
78 };
79
80 let mut body_sol_types = Vec::new();
82 for input in self.event.inputs.clone() {
83 if !input.indexed {
84 match input.resolve() {
85 Ok(st) => {
86 body_sol_types.push(st);
87 }
88 Err(_) => {
89 return Err(
90 QueryBuilderError::FailedToResolveSolTypesOfMatchedEvent(
91 self.event.clone(),
92 ),
93 );
94 }
95 }
96 }
97 }
98
99 let event_data_offsets =
102 match compute_abi_offsets(body_sol_types, &self.log.data().data) {
103 Ok(offsets) => offsets,
104 Err(_) => {
105 return Err(QueryBuilderError::FailedToGetEventDataOffsets(
106 Box::new(self.log.clone()),
107 ))
108 }
109 };
110
111 match event_data_offsets.get(data_index) {
112 Some(argument_field) => match argument_field.size {
113 Some(argument_field_size) => {
114 self.selected_offsets.push((
115 data_field.offset + argument_field.offset,
116 argument_field_size,
117 ));
118 return Ok(self);
119 }
120 None => {
121 return Err(QueryBuilderError::TryingToGetSizeOfDynamicType);
122 }
123 },
124 None => {
125 return Err(QueryBuilderError::MissingDataInAbiOffsets);
126 }
127 }
128 }
129 }
130
131 if !event_input.indexed {
132 data_index += 1;
133 }
134 }
135
136 Err(QueryBuilderError::MissingDataInAbiOffsets)
137 }
138
139 pub fn add_address(&mut self) -> Result<&mut Self, QueryBuilderError> {
140 match self.field.children.first() {
141 Some(address_field) => match address_field.size {
142 Some(address_field_size) => {
143 self.selected_offsets
144 .push((address_field.offset, address_field_size));
145 Ok(self)
146 }
147 None => Err(QueryBuilderError::TryingToGetSizeOfDynamicType),
148 },
149 None => Err(QueryBuilderError::MissingDataInAbiOffsets),
150 }
151 }
152
153 pub fn add_signature(&mut self) -> Result<&mut Self, QueryBuilderError> {
154 match self.field.children.get(1) {
156 Some(topics) => match topics.children.first() {
157 Some(signature_topic) => match signature_topic.size {
158 Some(size_of_topic) => {
159 let offset_and_size = (signature_topic.offset, size_of_topic);
160 self.selected_offsets.push(offset_and_size);
161 Ok(self)
162 }
163 None => Err(QueryBuilderError::TryingToGetSizeOfDynamicType),
164 },
165 None => Err(QueryBuilderError::MissingDataInAbiOffsets),
166 },
167 None => Err(QueryBuilderError::MissingDataInAbiOffsets),
168 }
169 }
170
171 pub fn get_selected_offsets(self) -> Vec<(usize, usize)> {
172 self.selected_offsets.clone()
173 }
174}