web3 7.9.0__py3-none-any.whl → 7.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
ens/exceptions.py CHANGED
@@ -32,7 +32,7 @@ class AddressMismatch(ENSException):
32
32
  class InvalidName(idna.IDNAError, ENSException):
33
33
  """
34
34
  Raised if the provided name does not meet the normalization
35
- standards specified in `ENSIP-15
35
+ standards specified in `ENSIP-15`
36
36
  <https://docs.ens.domains/ens-improvement-proposals/ensip-15-normalization-standard>`_.
37
37
  """
38
38
 
web3/_utils/abi.py CHANGED
@@ -131,7 +131,7 @@ def filter_by_argument_name(
131
131
  argument_names: Collection[str], contract_abi: ABI
132
132
  ) -> Sequence[ABIElement]:
133
133
  """
134
- Return a list of each ``ABIElement`` which contain arguments matching provided
134
+ Return a list of each ``ABIElement`` which contains arguments matching provided
135
135
  names.
136
136
  """
137
137
  abis_with_matching_args = []
@@ -153,7 +153,7 @@ def filter_by_argument_type(
153
153
  argument_types: Collection[str], contract_abi: ABI
154
154
  ) -> List[ABIElement]:
155
155
  """
156
- Return a list of each ``ABIElement`` which contain arguments matching provided
156
+ Return a list of each ``ABIElement`` which contains arguments matching provided
157
157
  types.
158
158
  """
159
159
  abis_with_matching_args = []
@@ -429,7 +429,7 @@ def find_constructor_abi_element_by_type(contract_abi: ABI) -> ABIConstructor:
429
429
  Find the constructor ABI element in the contract ABI.
430
430
 
431
431
  This function is often used in place of `web3.utils.abi.get_abi_element` to find
432
- a constructor without considering it's argument types. This is used prior to
432
+ a constructor without considering its argument types. This is used prior to
433
433
  encoding the abi, since the argument types are not known at that time.
434
434
  """
435
435
  candidates = [abi for abi in contract_abi if abi["type"] == "constructor"]
web3/_utils/batching.py CHANGED
@@ -1,6 +1,9 @@
1
1
  from copy import (
2
2
  copy,
3
3
  )
4
+ from functools import (
5
+ wraps,
6
+ )
4
7
  from types import (
5
8
  TracebackType,
6
9
  )
@@ -12,9 +15,11 @@ from typing import (
12
15
  Dict,
13
16
  Generic,
14
17
  List,
18
+ Protocol,
15
19
  Sequence,
16
20
  Tuple,
17
21
  Type,
22
+ TypeVar,
18
23
  Union,
19
24
  cast,
20
25
  )
@@ -33,6 +38,7 @@ from web3.exceptions import (
33
38
  Web3ValueError,
34
39
  )
35
40
  from web3.types import (
41
+ RPCEndpoint,
36
42
  TFunc,
37
43
  TReturn,
38
44
  )
@@ -55,7 +61,6 @@ if TYPE_CHECKING:
55
61
  JSONBaseProvider,
56
62
  )
57
63
  from web3.types import ( # noqa: F401
58
- RPCEndpoint,
59
64
  RPCResponse,
60
65
  )
61
66
 
@@ -201,7 +206,7 @@ def sort_batch_response_by_response_ids(
201
206
  responses: List["RPCResponse"],
202
207
  ) -> List["RPCResponse"]:
203
208
  if all(response.get("id") is not None for response in responses):
204
- # If all responses have an `id`, sort them by `id, since the JSON-RPC 2.0 spec
209
+ # If all responses have an `id`, sort them by `id`, since the JSON-RPC 2.0 spec
205
210
  # doesn't guarantee order.
206
211
  return sorted(responses, key=lambda response: response["id"])
207
212
  else:
@@ -215,3 +220,39 @@ def sort_batch_response_by_response_ids(
215
220
  stacklevel=2,
216
221
  )
217
222
  return responses
223
+
224
+
225
+ class SupportsBatching(Protocol):
226
+ _is_batching: bool
227
+
228
+
229
+ R = TypeVar("R")
230
+ T = TypeVar("T", bound=SupportsBatching)
231
+
232
+
233
+ def async_batching_context(
234
+ method: Callable[[T, List[Tuple[RPCEndpoint, Any]]], Coroutine[Any, Any, R]]
235
+ ) -> Callable[[T, List[Tuple[RPCEndpoint, Any]]], Coroutine[Any, Any, R]]:
236
+ @wraps(method)
237
+ async def wrapper(self: T, requests: List[Tuple[RPCEndpoint, Any]]) -> R:
238
+ self._is_batching = True
239
+ try:
240
+ return await method(self, requests)
241
+ finally:
242
+ self._is_batching = False
243
+
244
+ return wrapper
245
+
246
+
247
+ def batching_context(
248
+ method: Callable[[T, List[Tuple[RPCEndpoint, Any]]], R]
249
+ ) -> Callable[[T, List[Tuple[RPCEndpoint, Any]]], R]:
250
+ @wraps(method)
251
+ def wrapper(self: T, requests: List[Tuple[RPCEndpoint, Any]]) -> R:
252
+ self._is_batching = True
253
+ try:
254
+ return method(self, requests)
255
+ finally:
256
+ self._is_batching = False
257
+
258
+ return wrapper
web3/_utils/encoding.py CHANGED
@@ -36,6 +36,9 @@ from eth_utils.toolz import (
36
36
  from hexbytes import (
37
37
  HexBytes,
38
38
  )
39
+ from pydantic import (
40
+ BaseModel,
41
+ )
39
42
 
40
43
  from web3._utils.abi import (
41
44
  is_address_type,
@@ -299,6 +302,11 @@ class Web3JsonEncoder(json.JSONEncoder):
299
302
  return obj.__dict__
300
303
  elif isinstance(obj, (HexBytes, bytes)):
301
304
  return to_hex(obj)
305
+ elif isinstance(obj, BaseModel):
306
+ # TODO: For now we can assume all BaseModel objects behave this way, but
307
+ # internally we will start to use the CamelModel from eth-utils. Perhaps
308
+ # we should check for that type instead.
309
+ return obj.model_dump(by_alias=True)
302
310
  return json.JSONEncoder.default(self, obj)
303
311
 
304
312
 
web3/_utils/ens.py CHANGED
@@ -65,13 +65,21 @@ class StaticENS:
65
65
  return self.registry.get(name, None)
66
66
 
67
67
 
68
+ class AsyncStaticENS:
69
+ def __init__(self, name_addr_pairs: Dict[str, ChecksumAddress]) -> None:
70
+ self.registry = dict(name_addr_pairs)
71
+
72
+ async def address(self, name: str) -> ChecksumAddress:
73
+ return self.registry.get(name, None)
74
+
75
+
68
76
  @contextmanager
69
77
  def ens_addresses(
70
78
  w3: Union["Web3", "AsyncWeb3"], name_addr_pairs: Dict[str, ChecksumAddress]
71
79
  ) -> Iterator[None]:
72
80
  original_ens = w3.ens
73
81
  if w3.provider.is_async:
74
- w3.ens = cast(AsyncENS, StaticENS(name_addr_pairs))
82
+ w3.ens = cast(AsyncENS, AsyncStaticENS(name_addr_pairs))
75
83
  else:
76
84
  w3.ens = cast(ENS, StaticENS(name_addr_pairs))
77
85
  yield
@@ -47,6 +47,9 @@ from eth_utils.toolz import (
47
47
  from hexbytes import (
48
48
  HexBytes,
49
49
  )
50
+ from pydantic import (
51
+ BaseModel,
52
+ )
50
53
 
51
54
  from web3._utils.abi import (
52
55
  is_length,
@@ -161,6 +164,12 @@ def type_aware_apply_formatters_to_dict(
161
164
  """
162
165
  Preserve ``AttributeDict`` types if original ``value`` was an ``AttributeDict``.
163
166
  """
167
+ # TODO: In v8, Use eth-utils 5.3.0 as lower pin where ``apply_formatters_to_dict``
168
+ # already handles the CamelModel case, rather than generalizing to all BaseModel
169
+ # instances.
170
+ if isinstance(value, BaseModel):
171
+ value = value.model_dump(by_alias=True)
172
+
164
173
  formatted_dict: Dict[str, Any] = apply_formatters_to_dict(formatters, dict(value))
165
174
  return (
166
175
  AttributeDict.recursive(formatted_dict)
@@ -177,6 +186,9 @@ def type_aware_apply_formatters_to_dict_keys_and_values(
177
186
  """
178
187
  Preserve ``AttributeDict`` types if original ``value`` was an ``AttributeDict``.
179
188
  """
189
+ if isinstance(dict_like_object, BaseModel):
190
+ dict_like_object = dict_like_object.model_dump(by_alias=True)
191
+
180
192
  formatted_dict = {
181
193
  key_formatters(k): value_formatters(v) for k, v in dict_like_object.items()
182
194
  }
@@ -223,6 +235,22 @@ ACCESS_LIST_RESPONSE_FORMATTER = type_aware_apply_formatters_to_dict(
223
235
  }
224
236
  )
225
237
 
238
+ AUTH_LIST_RESULT_FORMATTER = apply_formatter_if(
239
+ is_not_null,
240
+ apply_formatter_to_array(
241
+ type_aware_apply_formatters_to_dict(
242
+ {
243
+ "chainId": to_integer_if_hex,
244
+ "address": to_checksum_address,
245
+ "nonce": to_integer_if_hex,
246
+ "yParity": to_integer_if_hex,
247
+ "r": to_hexbytes(32, variable_length=True),
248
+ "s": to_hexbytes(32, variable_length=True),
249
+ }
250
+ ),
251
+ ),
252
+ )
253
+
226
254
  TRANSACTION_RESULT_FORMATTERS = {
227
255
  "blockHash": apply_formatter_if(is_not_null, to_hexbytes(32)),
228
256
  "blockNumber": apply_formatter_if(is_not_null, to_integer_if_hex),
@@ -255,6 +283,7 @@ TRANSACTION_RESULT_FORMATTERS = {
255
283
  "blobVersionedHashes": apply_formatter_if(
256
284
  is_not_null, apply_formatter_to_array(to_hexbytes(32))
257
285
  ),
286
+ "authorizationList": AUTH_LIST_RESULT_FORMATTER,
258
287
  }
259
288
 
260
289
 
@@ -332,6 +361,7 @@ BLOCK_REQUEST_FORMATTERS = {
332
361
  "transactionsRoot": to_hex_if_bytes,
333
362
  "withdrawalsRoot": to_hex_if_bytes,
334
363
  "parentBeaconBlockRoot": to_hex_if_bytes,
364
+ "requestsHash": to_hex_if_bytes,
335
365
  }
336
366
  block_request_formatter = type_aware_apply_formatters_to_dict(BLOCK_REQUEST_FORMATTERS)
337
367
 
@@ -374,6 +404,7 @@ BLOCK_RESULT_FORMATTERS = {
374
404
  "blobGasUsed": to_integer_if_hex,
375
405
  "excessBlobGas": to_integer_if_hex,
376
406
  "parentBeaconBlockRoot": apply_formatter_if(is_not_null, to_hexbytes(32)),
407
+ "requestsHash": apply_formatter_if(is_not_null, to_hexbytes(32)),
377
408
  }
378
409
  block_result_formatter = type_aware_apply_formatters_to_dict(BLOCK_RESULT_FORMATTERS)
379
410
 
@@ -466,6 +497,22 @@ filter_result_formatter = apply_one_of_formatters(
466
497
  )
467
498
  )
468
499
 
500
+ AUTH_LIST_REQUEST_FORMATTER = apply_formatter_if(
501
+ is_not_null,
502
+ apply_formatter_to_array(
503
+ type_aware_apply_formatters_to_dict(
504
+ {
505
+ "chainId": to_hex_if_integer,
506
+ "address": to_checksum_address,
507
+ "nonce": to_hex_if_integer,
508
+ "yParity": to_hex_if_integer,
509
+ "r": to_hex_if_integer,
510
+ "s": to_hex_if_integer,
511
+ }
512
+ ),
513
+ ),
514
+ )
515
+
469
516
  TRANSACTION_REQUEST_FORMATTER = {
470
517
  "from": to_checksum_address,
471
518
  "to": apply_formatter_if(is_address, to_checksum_address),
@@ -477,12 +524,13 @@ TRANSACTION_REQUEST_FORMATTER = {
477
524
  "maxFeePerGas": to_hex_if_integer,
478
525
  "maxPriorityFeePerGas": to_hex_if_integer,
479
526
  "chainId": to_hex_if_integer,
527
+ "authorizationList": AUTH_LIST_REQUEST_FORMATTER,
480
528
  }
481
529
  transaction_request_formatter = type_aware_apply_formatters_to_dict(
482
530
  TRANSACTION_REQUEST_FORMATTER
483
531
  )
484
532
 
485
- ACCESS_LIST_REQUEST_FORMATTER = type_aware_apply_formatters_to_dict(
533
+ ETH_CALL_TX_FORMATTER = type_aware_apply_formatters_to_dict(
486
534
  {
487
535
  "accessList": apply_formatter_if(
488
536
  is_not_null,
@@ -494,10 +542,11 @@ ACCESS_LIST_REQUEST_FORMATTER = type_aware_apply_formatters_to_dict(
494
542
  )
495
543
  ),
496
544
  ),
545
+ "authorizationList": AUTH_LIST_REQUEST_FORMATTER,
497
546
  }
498
547
  )
499
548
  transaction_param_formatter = compose(
500
- ACCESS_LIST_REQUEST_FORMATTER,
549
+ ETH_CALL_TX_FORMATTER,
501
550
  remove_key_if("to", lambda txn: txn["to"] in {"", b"", None}),
502
551
  remove_key_if("gasPrice", lambda txn: txn["gasPrice"] in {"", b"", None}),
503
552
  )
@@ -1057,7 +1106,7 @@ def combine_formatters(
1057
1106
 
1058
1107
 
1059
1108
  def get_request_formatters(
1060
- method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]]
1109
+ method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
1061
1110
  ) -> Dict[str, Callable[..., Any]]:
1062
1111
  request_formatter_maps = (
1063
1112
  ABI_REQUEST_FORMATTERS,
@@ -1083,7 +1132,7 @@ def raise_block_not_found(params: Tuple[BlockIdentifier, bool]) -> NoReturn:
1083
1132
 
1084
1133
 
1085
1134
  def raise_block_not_found_for_uncle_at_index(
1086
- params: Tuple[BlockIdentifier, Union[HexStr, int]]
1135
+ params: Tuple[BlockIdentifier, Union[HexStr, int]],
1087
1136
  ) -> NoReturn:
1088
1137
  try:
1089
1138
  block_identifier = params[0]
@@ -1109,7 +1158,7 @@ def raise_transaction_not_found(params: Tuple[_Hash32]) -> NoReturn:
1109
1158
 
1110
1159
 
1111
1160
  def raise_transaction_not_found_with_index(
1112
- params: Tuple[BlockIdentifier, int]
1161
+ params: Tuple[BlockIdentifier, int],
1113
1162
  ) -> NoReturn:
1114
1163
  try:
1115
1164
  block_identifier = params[0]
@@ -1213,7 +1262,7 @@ def get_result_formatters(
1213
1262
 
1214
1263
 
1215
1264
  def get_error_formatters(
1216
- method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]]
1265
+ method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
1217
1266
  ) -> Callable[..., Any]:
1218
1267
  # Note error formatters work on the full response dict
1219
1268
  error_formatter_maps = (ERROR_FORMATTERS,)
@@ -1223,7 +1272,7 @@ def get_error_formatters(
1223
1272
 
1224
1273
 
1225
1274
  def get_null_result_formatters(
1226
- method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]]
1275
+ method_name: Union[RPCEndpoint, Callable[..., RPCEndpoint]],
1227
1276
  ) -> Callable[..., Any]:
1228
1277
  formatters = combine_formatters((NULL_RESULT_FORMATTERS,), method_name)
1229
1278