41
41
)
42
42
43
43
from web3 ._utils .events import (
44
+ AsyncEventFilterBuilder ,
44
45
EventFilterBuilder ,
45
46
construct_event_data_set ,
46
47
construct_event_topic_set ,
62
63
if TYPE_CHECKING :
63
64
from web3 import Web3 # noqa: F401
64
65
from web3 .eth import Eth # noqa: F401
66
+ from web3 .eth import AsyncEth # noqa: F401
65
67
66
68
67
69
def construct_event_filter_params (
@@ -126,14 +128,13 @@ def construct_event_filter_params(
126
128
return data_filters_set , filter_params
127
129
128
130
129
- class Filter :
131
+ class BaseFilter :
130
132
callbacks : List [Callable [..., Any ]] = None
131
133
stopped = False
132
134
poll_interval = None
133
135
filter_id = None
134
136
135
- def __init__ (self , filter_id : HexStr , eth_module : "Eth" ) -> None :
136
- self .eth_module = eth_module
137
+ def __init__ (self , filter_id : HexStr ) -> None :
137
138
self .filter_id = filter_id
138
139
self .callbacks = []
139
140
super ().__init__ ()
@@ -159,6 +160,23 @@ def _filter_valid_entries(
159
160
) -> Iterator [LogReceipt ]:
160
161
return filter (self .is_valid_entry , entries )
161
162
163
+ def _format_log_entries (
164
+ self , log_entries : Optional [Iterator [LogReceipt ]] = None
165
+ ) -> List [LogReceipt ]:
166
+ if log_entries is None :
167
+ return []
168
+
169
+ formatted_log_entries = [
170
+ self .format_entry (log_entry ) for log_entry in log_entries
171
+ ]
172
+ return formatted_log_entries
173
+
174
+
175
+ class Filter (BaseFilter ):
176
+ def __init__ (self , filter_id : HexStr , eth_module : "Eth" ) -> None :
177
+ self .eth_module = eth_module
178
+ super (Filter , self ).__init__ (filter_id )
179
+
162
180
def get_new_entries (self ) -> List [LogReceipt ]:
163
181
log_entries = self ._filter_valid_entries (
164
182
self .eth_module .get_filter_changes (self .filter_id )
@@ -171,26 +189,39 @@ def get_all_entries(self) -> List[LogReceipt]:
171
189
)
172
190
return self ._format_log_entries (log_entries )
173
191
174
- def _format_log_entries (
175
- self , log_entries : Optional [Iterator [LogReceipt ]] = None
176
- ) -> List [LogReceipt ]:
177
- if log_entries is None :
178
- return []
179
192
180
- formatted_log_entries = [
181
- self .format_entry (log_entry ) for log_entry in log_entries
182
- ]
183
- return formatted_log_entries
193
+ class AsyncFilter (BaseFilter ):
194
+ def __init__ (self , filter_id : HexStr , eth_module : "AsyncEth" ) -> None :
195
+ self .eth_module = eth_module
196
+ super (AsyncFilter , self ).__init__ (filter_id )
197
+
198
+ async def get_new_entries (self ) -> List [LogReceipt ]:
199
+ filter_changes = await self .eth_module .get_filter_changes (self .filter_id )
200
+ log_entries = self ._filter_valid_entries (filter_changes )
201
+ return self ._format_log_entries (log_entries )
202
+
203
+ async def get_all_entries (self ) -> List [LogReceipt ]:
204
+ filter_logs = await self .eth_module .get_filter_logs (self .filter_id )
205
+ log_entries = self ._filter_valid_entries (filter_logs )
206
+ return self ._format_log_entries (log_entries )
184
207
185
208
186
209
class BlockFilter (Filter ):
187
210
pass
188
211
189
212
213
+ class AsyncBlockFilter (AsyncFilter ):
214
+ pass
215
+
216
+
190
217
class TransactionFilter (Filter ):
191
218
pass
192
219
193
220
221
+ class AsyncTransactionFilter (AsyncFilter ):
222
+ pass
223
+
224
+
194
225
class LogFilter (Filter ):
195
226
data_filter_set = None
196
227
data_filter_set_regex = None
@@ -233,6 +264,48 @@ def is_valid_entry(self, entry: LogReceipt) -> bool:
233
264
return bool (self .data_filter_set_function (entry ["data" ]))
234
265
235
266
267
+ class AsyncLogFilter (AsyncFilter ):
268
+ data_filter_set = None
269
+ data_filter_set_regex = None
270
+ data_filter_set_function = None
271
+ log_entry_formatter = None
272
+ filter_params : FilterParams = None
273
+ builder : AsyncEventFilterBuilder = None
274
+
275
+ def __init__ (self , * args : Any , ** kwargs : Any ) -> None :
276
+ self .log_entry_formatter = kwargs .pop (
277
+ "log_entry_formatter" ,
278
+ self .log_entry_formatter ,
279
+ )
280
+ if "data_filter_set" in kwargs :
281
+ self .set_data_filters (kwargs .pop ("data_filter_set" ))
282
+ super ().__init__ (* args , ** kwargs )
283
+
284
+ def format_entry (self , entry : LogReceipt ) -> LogReceipt :
285
+ if self .log_entry_formatter :
286
+ return self .log_entry_formatter (entry )
287
+ return entry
288
+
289
+ def set_data_filters (
290
+ self , data_filter_set : Collection [Tuple [TypeStr , Any ]]
291
+ ) -> None :
292
+ """Sets the data filters (non indexed argument filters)
293
+
294
+ Expects a set of tuples with the type and value, e.g.:
295
+ (('uint256', [12345, 54321]), ('string', ('a-single-string',)))
296
+ """
297
+ self .data_filter_set = data_filter_set
298
+ if any (data_filter_set ):
299
+ self .data_filter_set_function = match_fn (
300
+ self .eth_module .codec , data_filter_set
301
+ )
302
+
303
+ def is_valid_entry (self , entry : LogReceipt ) -> bool :
304
+ if not self .data_filter_set :
305
+ return True
306
+ return bool (self .data_filter_set_function (entry ["data" ]))
307
+
308
+
236
309
def decode_utf8_bytes (value : bytes ) -> str :
237
310
return value .decode ("utf-8" )
238
311
0 commit comments