web3 7.0.0b2__py3-none-any.whl → 7.7.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.
Files changed (144) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +4 -4
  3. ens/async_ens.py +27 -15
  4. ens/base_ens.py +3 -1
  5. ens/contract_data.py +2 -2
  6. ens/ens.py +10 -7
  7. ens/exceptions.py +16 -29
  8. ens/specs/nf.json +1 -1
  9. ens/specs/normalization_spec.json +1 -1
  10. ens/utils.py +24 -32
  11. web3/__init__.py +23 -12
  12. web3/_utils/abi.py +157 -263
  13. web3/_utils/async_transactions.py +34 -20
  14. web3/_utils/batching.py +217 -0
  15. web3/_utils/blocks.py +6 -2
  16. web3/_utils/caching/__init__.py +12 -0
  17. web3/_utils/caching/caching_utils.py +433 -0
  18. web3/_utils/caching/request_caching_validation.py +287 -0
  19. web3/_utils/compat/__init__.py +2 -3
  20. web3/_utils/contract_sources/compile_contracts.py +1 -1
  21. web3/_utils/contract_sources/contract_data/ambiguous_function_contract.py +42 -0
  22. web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
  23. web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
  24. web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
  25. web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
  26. web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
  27. web3/_utils/contract_sources/contract_data/event_contracts.py +50 -5
  28. web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
  29. web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
  30. web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
  31. web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
  32. web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
  33. web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
  34. web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
  35. web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
  36. web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
  37. web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
  38. web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
  39. web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
  40. web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
  41. web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
  42. web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
  43. web3/_utils/contracts.py +172 -220
  44. web3/_utils/datatypes.py +5 -1
  45. web3/_utils/decorators.py +6 -1
  46. web3/_utils/empty.py +1 -1
  47. web3/_utils/encoding.py +16 -12
  48. web3/_utils/error_formatters_utils.py +5 -3
  49. web3/_utils/events.py +78 -72
  50. web3/_utils/fee_utils.py +1 -3
  51. web3/_utils/filters.py +24 -22
  52. web3/_utils/formatters.py +2 -2
  53. web3/_utils/http.py +8 -2
  54. web3/_utils/http_session_manager.py +314 -0
  55. web3/_utils/math.py +14 -15
  56. web3/_utils/method_formatters.py +161 -34
  57. web3/_utils/module.py +2 -1
  58. web3/_utils/module_testing/__init__.py +3 -2
  59. web3/_utils/module_testing/eth_module.py +736 -583
  60. web3/_utils/module_testing/go_ethereum_debug_module.py +128 -0
  61. web3/_utils/module_testing/module_testing_utils.py +81 -24
  62. web3/_utils/module_testing/persistent_connection_provider.py +702 -220
  63. web3/_utils/module_testing/utils.py +114 -33
  64. web3/_utils/module_testing/web3_module.py +438 -17
  65. web3/_utils/normalizers.py +13 -11
  66. web3/_utils/rpc_abi.py +10 -22
  67. web3/_utils/threads.py +8 -7
  68. web3/_utils/transactions.py +32 -25
  69. web3/_utils/type_conversion.py +5 -1
  70. web3/_utils/validation.py +20 -17
  71. web3/beacon/__init__.py +5 -0
  72. web3/beacon/api_endpoints.py +3 -0
  73. web3/beacon/async_beacon.py +29 -6
  74. web3/beacon/beacon.py +24 -6
  75. web3/contract/__init__.py +7 -0
  76. web3/contract/async_contract.py +285 -82
  77. web3/contract/base_contract.py +556 -258
  78. web3/contract/contract.py +295 -84
  79. web3/contract/utils.py +251 -55
  80. web3/datastructures.py +49 -34
  81. web3/eth/__init__.py +7 -0
  82. web3/eth/async_eth.py +89 -69
  83. web3/eth/base_eth.py +7 -3
  84. web3/eth/eth.py +43 -66
  85. web3/exceptions.py +158 -83
  86. web3/gas_strategies/time_based.py +8 -6
  87. web3/geth.py +53 -184
  88. web3/main.py +77 -17
  89. web3/manager.py +362 -95
  90. web3/method.py +43 -15
  91. web3/middleware/__init__.py +17 -0
  92. web3/middleware/attrdict.py +12 -22
  93. web3/middleware/base.py +55 -2
  94. web3/middleware/filter.py +45 -23
  95. web3/middleware/formatting.py +6 -3
  96. web3/middleware/names.py +4 -1
  97. web3/middleware/signing.py +15 -6
  98. web3/middleware/stalecheck.py +2 -1
  99. web3/module.py +61 -25
  100. web3/providers/__init__.py +21 -0
  101. web3/providers/async_base.py +87 -32
  102. web3/providers/base.py +77 -32
  103. web3/providers/eth_tester/__init__.py +5 -0
  104. web3/providers/eth_tester/defaults.py +2 -55
  105. web3/providers/eth_tester/main.py +41 -15
  106. web3/providers/eth_tester/middleware.py +16 -17
  107. web3/providers/ipc.py +41 -17
  108. web3/providers/legacy_websocket.py +26 -1
  109. web3/providers/persistent/__init__.py +7 -0
  110. web3/providers/persistent/async_ipc.py +61 -121
  111. web3/providers/persistent/persistent.py +323 -16
  112. web3/providers/persistent/persistent_connection.py +54 -5
  113. web3/providers/persistent/request_processor.py +136 -56
  114. web3/providers/persistent/subscription_container.py +56 -0
  115. web3/providers/persistent/subscription_manager.py +233 -0
  116. web3/providers/persistent/websocket.py +29 -92
  117. web3/providers/rpc/__init__.py +5 -0
  118. web3/providers/rpc/async_rpc.py +73 -18
  119. web3/providers/rpc/rpc.py +73 -30
  120. web3/providers/rpc/utils.py +1 -13
  121. web3/scripts/install_pre_releases.py +33 -0
  122. web3/scripts/parse_pygeth_version.py +16 -0
  123. web3/testing.py +4 -4
  124. web3/tracing.py +9 -5
  125. web3/types.py +141 -74
  126. web3/utils/__init__.py +64 -5
  127. web3/utils/abi.py +790 -10
  128. web3/utils/address.py +8 -0
  129. web3/utils/async_exception_handling.py +20 -11
  130. web3/utils/caching.py +34 -4
  131. web3/utils/exception_handling.py +9 -12
  132. web3/utils/subscriptions.py +285 -0
  133. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/LICENSE +1 -1
  134. web3-7.7.0.dist-info/METADATA +130 -0
  135. web3-7.7.0.dist-info/RECORD +171 -0
  136. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/WHEEL +1 -1
  137. web3/_utils/caching.py +0 -155
  138. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  139. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -300
  140. web3/_utils/request.py +0 -265
  141. web3-7.0.0b2.dist-info/METADATA +0 -106
  142. web3-7.0.0b2.dist-info/RECORD +0 -163
  143. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
  144. {web3-7.0.0b2.dist-info → web3-7.7.0.dist-info}/top_level.txt +0 -0
web3/utils/address.py CHANGED
@@ -9,6 +9,9 @@ from eth_utils import (
9
9
  )
10
10
  import rlp
11
11
 
12
+ from web3.exceptions import (
13
+ Web3ValidationError,
14
+ )
12
15
  from web3.types import (
13
16
  HexStr,
14
17
  Nonce,
@@ -30,6 +33,11 @@ def get_create2_address(
30
33
  Determine the resulting `CREATE2` opcode contract address for a sender, salt and
31
34
  bytecode.
32
35
  """
36
+ if len(to_bytes(hexstr=salt)) != 32:
37
+ raise Web3ValidationError(
38
+ f"`salt` must be 32 bytes, {len(to_bytes(hexstr=salt))} != 32"
39
+ )
40
+
33
41
  contract_address = keccak(
34
42
  b"\xff"
35
43
  + to_bytes(hexstr=sender)
@@ -3,6 +3,10 @@ from typing import (
3
3
  Dict,
4
4
  )
5
5
 
6
+ from aiohttp import (
7
+ ClientSession,
8
+ ClientTimeout,
9
+ )
6
10
  from eth_abi import (
7
11
  abi,
8
12
  )
@@ -10,10 +14,8 @@ from eth_typing import (
10
14
  URI,
11
15
  )
12
16
 
13
- from web3._utils.request import (
14
- async_get_json_from_client_response,
15
- async_get_response_from_get_request,
16
- async_get_response_from_post_request,
17
+ from web3._utils.http import (
18
+ DEFAULT_HTTP_TIMEOUT,
17
19
  )
18
20
  from web3._utils.type_conversion import (
19
21
  to_bytes_if_hex,
@@ -41,6 +43,7 @@ async def async_handle_offchain_lookup(
41
43
  "`sender` value does not equal `to` address in transaction."
42
44
  )
43
45
 
46
+ session = ClientSession()
44
47
  for url in offchain_lookup_payload["urls"]:
45
48
  formatted_url = URI(
46
49
  str(url)
@@ -50,27 +53,30 @@ async def async_handle_offchain_lookup(
50
53
 
51
54
  try:
52
55
  if "{data}" in url and "{sender}" in url:
53
- response = await async_get_response_from_get_request(formatted_url)
54
- elif "{sender}" in url:
55
- response = await async_get_response_from_post_request(
56
- formatted_url,
57
- data={"data": formatted_data, "sender": formatted_sender},
56
+ response = await session.get(
57
+ formatted_url, timeout=ClientTimeout(DEFAULT_HTTP_TIMEOUT)
58
58
  )
59
59
  else:
60
- raise Web3ValidationError("url not formatted properly.")
60
+ response = await session.post(
61
+ formatted_url,
62
+ json={"data": formatted_data, "sender": formatted_sender},
63
+ timeout=ClientTimeout(DEFAULT_HTTP_TIMEOUT),
64
+ )
61
65
  except Exception:
62
66
  continue # try next url if timeout or issues making the request
63
67
 
64
68
  if (
65
69
  400 <= response.status <= 499
66
70
  ): # if request returns 400 error, raise exception
71
+ await session.close()
67
72
  response.raise_for_status()
68
73
  if not 200 <= response.status <= 299: # if not 400 error, try next url
69
74
  continue
70
75
 
71
- result = await async_get_json_from_client_response(response)
76
+ result = await response.json()
72
77
 
73
78
  if "data" not in result.keys():
79
+ await session.close()
74
80
  raise Web3ValidationError(
75
81
  "Improperly formatted response for offchain lookup HTTP request"
76
82
  " - missing 'data' field."
@@ -91,5 +97,8 @@ async def async_handle_offchain_lookup(
91
97
  ]
92
98
  )
93
99
 
100
+ await session.close()
94
101
  return encoded_data_with_function_selector
102
+
103
+ await session.close()
95
104
  raise MultipleFailedRequests("Offchain lookup failed for supplied urls.")
web3/utils/caching.py CHANGED
@@ -1,6 +1,11 @@
1
+ import asyncio
1
2
  from collections import (
2
3
  OrderedDict,
3
4
  )
5
+ from enum import (
6
+ Enum,
7
+ )
8
+ import time
4
9
  from typing import (
5
10
  Any,
6
11
  Dict,
@@ -10,28 +15,31 @@ from typing import (
10
15
  )
11
16
 
12
17
 
18
+ class RequestCacheValidationThreshold(Enum):
19
+ FINALIZED = "finalized"
20
+ SAFE = "safe"
21
+
22
+
13
23
  class SimpleCache:
14
24
  def __init__(self, size: int = 100):
15
25
  self._size = size
16
26
  self._data: OrderedDict[str, Any] = OrderedDict()
17
27
 
18
28
  def cache(self, key: str, value: Any) -> Tuple[Any, Dict[str, Any]]:
19
- evicted_items = None
29
+ evicted_items = {}
20
30
  # If the key is already in the OrderedDict just update it
21
31
  # and don't evict any values. Ideally, we could still check to see
22
32
  # if there are too many items in the OrderedDict but that may rearrange
23
33
  # the order it should be unlikely that the size could grow over the limit
24
34
  if key not in self._data:
25
35
  while len(self._data) >= self._size:
26
- if evicted_items is None:
27
- evicted_items = {}
28
36
  k, v = self._data.popitem(last=False)
29
37
  evicted_items[k] = v
30
38
  self._data[key] = value
31
39
 
32
40
  # Return the cached value along with the evicted items at the same time. No
33
41
  # need to reach back into the cache to grab the value.
34
- return value, evicted_items
42
+ return value, evicted_items or None
35
43
 
36
44
  def get_cache_entry(self, key: str) -> Optional[Any]:
37
45
  return self._data[key] if key in self._data else None
@@ -48,8 +56,30 @@ class SimpleCache:
48
56
 
49
57
  return self._data.pop(key)
50
58
 
59
+ def popitem(self, last: bool = True) -> Tuple[str, Any]:
60
+ return self._data.popitem(last=last)
61
+
51
62
  def __contains__(self, key: str) -> bool:
52
63
  return key in self._data
53
64
 
54
65
  def __len__(self) -> int:
55
66
  return len(self._data)
67
+
68
+ # -- async utility methods -- #
69
+
70
+ async def async_await_and_popitem(
71
+ self, last: bool = True, timeout: float = 10.0
72
+ ) -> Tuple[str, Any]:
73
+ start = time.time()
74
+ end_time = start + timeout
75
+ while True:
76
+ await asyncio.sleep(0)
77
+ try:
78
+ return self.popitem(last=last)
79
+ except KeyError:
80
+ now = time.time()
81
+ if now >= end_time:
82
+ raise asyncio.TimeoutError(
83
+ "Timeout waiting for item to be available"
84
+ )
85
+ await asyncio.sleep(min(0.1, end_time - now))
@@ -9,10 +9,10 @@ from eth_abi import (
9
9
  from eth_typing import (
10
10
  URI,
11
11
  )
12
+ import requests
12
13
 
13
- from web3._utils.request import (
14
- get_response_from_get_request,
15
- get_response_from_post_request,
14
+ from web3._utils.http import (
15
+ DEFAULT_HTTP_TIMEOUT,
16
16
  )
17
17
  from web3._utils.type_conversion import (
18
18
  to_bytes_if_hex,
@@ -40,6 +40,7 @@ def handle_offchain_lookup(
40
40
  "Returned `sender` value does not equal `to` address in transaction."
41
41
  )
42
42
 
43
+ session = requests.Session()
43
44
  for url in offchain_lookup_payload["urls"]:
44
45
  formatted_url = URI(
45
46
  str(url)
@@ -49,17 +50,13 @@ def handle_offchain_lookup(
49
50
 
50
51
  try:
51
52
  if "{data}" in url and "{sender}" in url:
52
- response = get_response_from_get_request(formatted_url)
53
- elif "{sender}" in url:
54
- response = get_response_from_post_request(
53
+ response = session.get(formatted_url, timeout=DEFAULT_HTTP_TIMEOUT)
54
+ else:
55
+ response = session.post(
55
56
  formatted_url,
56
- data={
57
- "data": formatted_data,
58
- "sender": formatted_sender,
59
- },
57
+ json={"data": formatted_data, "sender": formatted_sender},
58
+ timeout=DEFAULT_HTTP_TIMEOUT,
60
59
  )
61
- else:
62
- raise Web3ValidationError("url not formatted properly.")
63
60
  except Exception:
64
61
  continue # try next url if timeout or issues making the request
65
62
 
@@ -0,0 +1,285 @@
1
+ from typing import (
2
+ TYPE_CHECKING,
3
+ Any,
4
+ Callable,
5
+ Coroutine,
6
+ Dict,
7
+ Generic,
8
+ List,
9
+ Optional,
10
+ Sequence,
11
+ TypeVar,
12
+ Union,
13
+ )
14
+
15
+ from eth_typing import (
16
+ Address,
17
+ ChecksumAddress,
18
+ HexStr,
19
+ )
20
+ from hexbytes import (
21
+ HexBytes,
22
+ )
23
+
24
+ from web3.exceptions import (
25
+ Web3AttributeError,
26
+ Web3ValueError,
27
+ )
28
+ from web3.types import (
29
+ BlockData,
30
+ FilterParams,
31
+ LogReceipt,
32
+ SyncProgress,
33
+ TxData,
34
+ )
35
+
36
+ if TYPE_CHECKING:
37
+ from web3 import (
38
+ AsyncWeb3,
39
+ )
40
+ from web3.providers.persistent.subscription_manager import (
41
+ SubscriptionManager,
42
+ )
43
+ from web3.types import EthSubscriptionResult # noqa: F401
44
+
45
+
46
+ TSubscriptionResult = TypeVar("TSubscriptionResult", bound="EthSubscriptionResult")
47
+ TSubscription = TypeVar("TSubscription", bound="EthSubscription[Any]")
48
+
49
+
50
+ class EthSubscriptionContext(Generic[TSubscription, TSubscriptionResult]):
51
+ def __init__(
52
+ self,
53
+ async_w3: "AsyncWeb3",
54
+ subscription: TSubscription,
55
+ result: TSubscriptionResult,
56
+ **kwargs: Any,
57
+ ) -> None:
58
+ self.async_w3 = async_w3
59
+ self.subscription = subscription
60
+ self.result = result
61
+ self.__dict__.update(kwargs)
62
+
63
+ def __getattr__(self, item: str) -> Any:
64
+ if item in self.__dict__:
65
+ return self.__dict__[item]
66
+ raise Web3AttributeError(
67
+ f"'{self.__class__.__name__}' object has no attribute '{item}'"
68
+ )
69
+
70
+
71
+ EthSubscriptionHandler = Callable[
72
+ [EthSubscriptionContext[Any, Any]], Coroutine[Any, Any, None]
73
+ ]
74
+
75
+
76
+ def handler_wrapper(
77
+ handler: Optional[EthSubscriptionHandler],
78
+ ) -> Optional[EthSubscriptionHandler]:
79
+ """Wrap the handler to add bookkeeping and context creation."""
80
+ if handler is None:
81
+ return None
82
+
83
+ async def wrapped_handler(
84
+ context: EthSubscriptionContext[TSubscription, TSubscriptionResult],
85
+ ) -> None:
86
+ sub = context.subscription
87
+ sub.handler_call_count += 1
88
+ sub.manager.total_handler_calls += 1
89
+ sub.manager.logger.debug(
90
+ f"Subscription handler called.\n"
91
+ f" label: {sub.label}\n"
92
+ f" call count: {sub.handler_call_count}\n"
93
+ f" total handler calls: {sub.manager.total_handler_calls}"
94
+ )
95
+ await handler(context)
96
+
97
+ return wrapped_handler
98
+
99
+
100
+ class EthSubscription(Generic[TSubscriptionResult]):
101
+ _id: HexStr = None
102
+ manager: "SubscriptionManager" = None
103
+
104
+ def __init__(
105
+ self: TSubscription,
106
+ subscription_params: Optional[Sequence[Any]] = None,
107
+ handler: Optional[EthSubscriptionHandler] = None,
108
+ handler_context: Optional[Dict[str, Any]] = None,
109
+ label: Optional[str] = None,
110
+ ) -> None:
111
+ self._subscription_params = subscription_params
112
+ self._handler = handler_wrapper(handler)
113
+ self._handler_context = handler_context or {}
114
+ self._label = label
115
+ self.handler_call_count = 0
116
+
117
+ @classmethod
118
+ def _create_type_aware_subscription(
119
+ cls,
120
+ subscription_params: Optional[Sequence[Any]],
121
+ handler: Optional[EthSubscriptionHandler] = None,
122
+ handler_context: Optional[Dict[str, Any]] = None,
123
+ label: Optional[str] = None,
124
+ ) -> "EthSubscription[Any]":
125
+ subscription_type = subscription_params[0]
126
+ subscription_arg = (
127
+ subscription_params[1] if len(subscription_params) > 1 else None
128
+ )
129
+ if subscription_type == "newHeads":
130
+ return NewHeadsSubscription(
131
+ handler=handler, handler_context=handler_context, label=label
132
+ )
133
+ elif subscription_type == "logs":
134
+ subscription_arg = subscription_arg or {}
135
+ return LogsSubscription(
136
+ **subscription_arg,
137
+ handler=handler,
138
+ handler_context=handler_context,
139
+ label=label,
140
+ )
141
+ elif subscription_type == "newPendingTransactions":
142
+ subscription_arg = subscription_arg or False
143
+ return PendingTxSubscription(
144
+ full_transactions=subscription_arg,
145
+ handler=handler,
146
+ handler_context=handler_context,
147
+ label=label,
148
+ )
149
+ elif subscription_type == "syncing":
150
+ return SyncingSubscription(
151
+ handler=handler, handler_context=handler_context, label=label
152
+ )
153
+ else:
154
+ params = (
155
+ (subscription_type, subscription_arg)
156
+ if subscription_arg
157
+ else (subscription_type,)
158
+ )
159
+ return cls(
160
+ params,
161
+ handler=handler,
162
+ handler_context=handler_context,
163
+ label=label,
164
+ )
165
+
166
+ @property
167
+ def subscription_params(self) -> Sequence[Any]:
168
+ return self._subscription_params
169
+
170
+ @property
171
+ def label(self) -> str:
172
+ if not self._label:
173
+ self._label = f"{self.__class__.__name__}{self.subscription_params}"
174
+ return self._label
175
+
176
+ @property
177
+ def id(self) -> HexStr:
178
+ if not self._id:
179
+ raise Web3ValueError("No `id` found for subscription.")
180
+ return self._id
181
+
182
+ async def unsubscribe(self) -> bool:
183
+ return await self.manager.unsubscribe(self)
184
+
185
+
186
+ LogsSubscriptionContext = EthSubscriptionContext[
187
+ "LogsSubscription", "EthSubscriptionResult"
188
+ ]
189
+ LogsSubscriptionHandler = Callable[[LogsSubscriptionContext], Coroutine[Any, Any, None]]
190
+
191
+
192
+ class LogsSubscription(EthSubscription[LogReceipt]):
193
+ def __init__(
194
+ self,
195
+ address: Optional[
196
+ Union[Address, ChecksumAddress, List[Address], List[ChecksumAddress]]
197
+ ] = None,
198
+ topics: Optional[List[HexStr]] = None,
199
+ handler: LogsSubscriptionHandler = None,
200
+ handler_context: Optional[Dict[str, Any]] = None,
201
+ label: Optional[str] = None,
202
+ ) -> None:
203
+ self.address = address
204
+ self.topics = topics
205
+
206
+ logs_filter: FilterParams = {}
207
+ if address:
208
+ logs_filter["address"] = address
209
+ if topics:
210
+ logs_filter["topics"] = topics
211
+ self.logs_filter = logs_filter
212
+
213
+ super().__init__(
214
+ subscription_params=("logs", logs_filter),
215
+ handler=handler,
216
+ handler_context=handler_context,
217
+ label=label,
218
+ )
219
+
220
+
221
+ NewHeadsSubscriptionContext = EthSubscriptionContext["NewHeadsSubscription", BlockData]
222
+ NewHeadsSubscriptionHandler = Callable[
223
+ [NewHeadsSubscriptionContext], Coroutine[Any, Any, None]
224
+ ]
225
+
226
+
227
+ class NewHeadsSubscription(EthSubscription[BlockData]):
228
+ def __init__(
229
+ self,
230
+ label: Optional[str] = None,
231
+ handler: Optional[NewHeadsSubscriptionHandler] = None,
232
+ handler_context: Optional[Dict[str, Any]] = None,
233
+ ) -> None:
234
+ super().__init__(
235
+ subscription_params=("newHeads",),
236
+ handler=handler,
237
+ handler_context=handler_context,
238
+ label=label,
239
+ )
240
+
241
+
242
+ PendingTxSubscriptionContext = EthSubscriptionContext[
243
+ "PendingTxSubscription", Union[HexBytes, TxData]
244
+ ]
245
+ PendingTxSubscriptionHandler = Callable[
246
+ [PendingTxSubscriptionContext], Coroutine[Any, Any, None]
247
+ ]
248
+
249
+
250
+ class PendingTxSubscription(EthSubscription[Union[HexBytes, TxData]]):
251
+ def __init__(
252
+ self,
253
+ full_transactions: bool = False,
254
+ label: Optional[str] = None,
255
+ handler: Optional[PendingTxSubscriptionHandler] = None,
256
+ handler_context: Optional[Dict[str, Any]] = None,
257
+ ) -> None:
258
+ self.full_transactions = full_transactions
259
+ super().__init__(
260
+ subscription_params=("newPendingTransactions", full_transactions),
261
+ handler=handler,
262
+ handler_context=handler_context,
263
+ label=label,
264
+ )
265
+
266
+
267
+ SyncingSubscriptionContext = EthSubscriptionContext["SyncingSubscription", SyncProgress]
268
+ SyncingSubscriptionHandler = Callable[
269
+ [SyncingSubscriptionContext], Coroutine[Any, Any, None]
270
+ ]
271
+
272
+
273
+ class SyncingSubscription(EthSubscription[SyncProgress]):
274
+ def __init__(
275
+ self,
276
+ label: Optional[str] = None,
277
+ handler: Optional[SyncingSubscriptionHandler] = None,
278
+ handler_context: Optional[Dict[str, Any]] = None,
279
+ ) -> None:
280
+ super().__init__(
281
+ subscription_params=("syncing",),
282
+ handler=handler,
283
+ handler_context=handler_context,
284
+ label=label,
285
+ )
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 The Ethereum Foundation
3
+ Copyright (c) 2016-2024 The Ethereum Foundation
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.2
2
+ Name: web3
3
+ Version: 7.7.0
4
+ Summary: web3: A Python library for interacting with Ethereum
5
+ Home-page: https://github.com/ethereum/web3.py
6
+ Author: The Ethereum Foundation
7
+ Author-email: snakecharmers@ethereum.org
8
+ License: MIT
9
+ Keywords: ethereum
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Natural Language :: English
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Python: >=3.8, <4
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: eth-abi>=5.0.1
25
+ Requires-Dist: eth-account>=0.13.1
26
+ Requires-Dist: eth-hash[pycryptodome]>=0.5.1
27
+ Requires-Dist: eth-typing>=5.0.0
28
+ Requires-Dist: eth-utils>=5.0.0
29
+ Requires-Dist: hexbytes>=1.2.0
30
+ Requires-Dist: aiohttp>=3.7.4.post0
31
+ Requires-Dist: pydantic>=2.4.0
32
+ Requires-Dist: pywin32>=223; platform_system == "Windows"
33
+ Requires-Dist: requests>=2.23.0
34
+ Requires-Dist: typing-extensions>=4.0.1
35
+ Requires-Dist: types-requests>=2.0.0
36
+ Requires-Dist: websockets<14.0.0,>=10.0.0
37
+ Requires-Dist: pyunormalize>=15.0.0
38
+ Provides-Extra: tester
39
+ Requires-Dist: eth-tester[py-evm]<0.13.0b1,>=0.12.0b1; extra == "tester"
40
+ Requires-Dist: py-geth>=5.1.0; extra == "tester"
41
+ Provides-Extra: dev
42
+ Requires-Dist: build>=0.9.0; extra == "dev"
43
+ Requires-Dist: bumpversion>=0.5.3; extra == "dev"
44
+ Requires-Dist: ipython; extra == "dev"
45
+ Requires-Dist: setuptools>=38.6.0; extra == "dev"
46
+ Requires-Dist: tqdm>4.32; extra == "dev"
47
+ Requires-Dist: twine>=1.13; extra == "dev"
48
+ Requires-Dist: wheel; extra == "dev"
49
+ Requires-Dist: sphinx>=6.0.0; extra == "dev"
50
+ Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "dev"
51
+ Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "dev"
52
+ Requires-Dist: towncrier<22,>=21; extra == "dev"
53
+ Requires-Dist: pytest-asyncio<0.23,>=0.18.1; extra == "dev"
54
+ Requires-Dist: pytest-mock>=1.10; extra == "dev"
55
+ Requires-Dist: pytest-xdist>=2.4.0; extra == "dev"
56
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
57
+ Requires-Dist: flaky>=3.7.0; extra == "dev"
58
+ Requires-Dist: hypothesis>=3.31.2; extra == "dev"
59
+ Requires-Dist: tox>=4.0.0; extra == "dev"
60
+ Requires-Dist: mypy==1.10.0; extra == "dev"
61
+ Requires-Dist: pre-commit>=3.4.0; extra == "dev"
62
+ Requires-Dist: eth-tester[py-evm]<0.13.0b1,>=0.12.0b1; extra == "dev"
63
+ Requires-Dist: py-geth>=5.1.0; extra == "dev"
64
+ Provides-Extra: docs
65
+ Requires-Dist: sphinx>=6.0.0; extra == "docs"
66
+ Requires-Dist: sphinx-autobuild>=2021.3.14; extra == "docs"
67
+ Requires-Dist: sphinx_rtd_theme>=1.0.0; extra == "docs"
68
+ Requires-Dist: towncrier<22,>=21; extra == "docs"
69
+ Provides-Extra: test
70
+ Requires-Dist: pytest-asyncio<0.23,>=0.18.1; extra == "test"
71
+ Requires-Dist: pytest-mock>=1.10; extra == "test"
72
+ Requires-Dist: pytest-xdist>=2.4.0; extra == "test"
73
+ Requires-Dist: pytest>=7.0.0; extra == "test"
74
+ Requires-Dist: flaky>=3.7.0; extra == "test"
75
+ Requires-Dist: hypothesis>=3.31.2; extra == "test"
76
+ Requires-Dist: tox>=4.0.0; extra == "test"
77
+ Requires-Dist: mypy==1.10.0; extra == "test"
78
+ Requires-Dist: pre-commit>=3.4.0; extra == "test"
79
+ Requires-Dist: eth-tester[py-evm]<0.13.0b1,>=0.12.0b1; extra == "test"
80
+ Requires-Dist: py-geth>=5.1.0; extra == "test"
81
+ Dynamic: author
82
+ Dynamic: author-email
83
+ Dynamic: classifier
84
+ Dynamic: description
85
+ Dynamic: description-content-type
86
+ Dynamic: home-page
87
+ Dynamic: keywords
88
+ Dynamic: license
89
+ Dynamic: provides-extra
90
+ Dynamic: requires-dist
91
+ Dynamic: requires-python
92
+ Dynamic: summary
93
+
94
+ # web3.py
95
+
96
+ [![Join the conversation on Discord](https://img.shields.io/discord/809793915578089484?color=blue&label=chat&logo=discord&logoColor=white)](https://discord.gg/GHryRvPB84)
97
+ [![Build Status](https://circleci.com/gh/ethereum/web3.py.svg?style=shield)](https://circleci.com/gh/ethereum/web3.py)
98
+ [![PyPI version](https://badge.fury.io/py/web3.svg)](https://badge.fury.io/py/web3)
99
+ [![Python versions](https://img.shields.io/pypi/pyversions/web3.svg)](https://pypi.python.org/pypi/web3)
100
+ [![Docs build](https://readthedocs.org/projects/web3py/badge/?version=latest)](https://web3py.readthedocs.io/en/latest/?badge=latest)
101
+
102
+ ## A Python Library for Interacting with Ethereum
103
+
104
+ web3.py allows you to interact with the Ethereum blockchain using Python, enabling you to build decentralized applications, interact with smart contracts, and much more.
105
+
106
+ - Python 3.8+ support
107
+
108
+ ______________________________________________________________________
109
+
110
+ ## Quickstart
111
+
112
+ [Get started in 5 minutes](https://web3py.readthedocs.io/en/latest/quickstart.html) or
113
+ [take a tour](https://web3py.readthedocs.io/en/latest/overview.html) of the library.
114
+
115
+ ## Documentation
116
+
117
+ For additional guides, examples, and APIs, see the [documentation](https://web3py.readthedocs.io/en/latest/).
118
+
119
+ ## Want to Help?
120
+
121
+ Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our
122
+ guidelines for [contributing](https://web3py.readthedocs.io/en/latest/contributing.html),
123
+ then check out issues that are labeled
124
+ [Good First Issue](https://github.com/ethereum/web3.py/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+First+Issue%22).
125
+
126
+ ______________________________________________________________________
127
+
128
+ ## Questions on Implementation or Usage?
129
+
130
+ Join the conversation in the Ethereum Python Community [Discord](https://discord.gg/GHryRvPB84).