web3 6.20.2__py3-none-any.whl → 7.0.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 (270) hide show
  1. ens/__init__.py +13 -2
  2. ens/_normalization.py +2 -17
  3. ens/async_ens.py +33 -21
  4. ens/base_ens.py +3 -1
  5. ens/ens.py +16 -11
  6. ens/exceptions.py +16 -29
  7. ens/specs/nf.json +1 -1
  8. ens/specs/normalization_spec.json +1 -1
  9. ens/utils.py +52 -63
  10. web3/__init__.py +20 -24
  11. web3/_utils/abi.py +115 -271
  12. web3/_utils/async_transactions.py +7 -4
  13. web3/_utils/batching.py +217 -0
  14. web3/_utils/blocks.py +6 -2
  15. web3/_utils/caching.py +128 -5
  16. web3/_utils/compat/__init__.py +2 -3
  17. web3/_utils/contract_sources/compile_contracts.py +1 -1
  18. web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
  19. web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
  20. web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
  21. web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
  22. web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
  23. web3/_utils/contract_sources/contract_data/event_contracts.py +5 -5
  24. web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
  25. web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
  26. web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
  27. web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
  28. web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
  29. web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
  30. web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
  31. web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
  32. web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
  33. web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
  34. web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
  35. web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
  36. web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
  37. web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
  38. web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
  39. web3/_utils/contracts.py +130 -236
  40. web3/_utils/datatypes.py +5 -1
  41. web3/_utils/decorators.py +13 -23
  42. web3/_utils/empty.py +1 -1
  43. web3/_utils/encoding.py +16 -12
  44. web3/_utils/ens.py +2 -1
  45. web3/_utils/error_formatters_utils.py +5 -3
  46. web3/_utils/events.py +66 -69
  47. web3/_utils/fee_utils.py +1 -3
  48. web3/_utils/filters.py +24 -22
  49. web3/_utils/formatters.py +2 -2
  50. web3/_utils/http.py +5 -3
  51. web3/_utils/http_session_manager.py +303 -0
  52. web3/_utils/math.py +14 -15
  53. web3/_utils/method_formatters.py +34 -36
  54. web3/_utils/module.py +2 -1
  55. web3/_utils/module_testing/__init__.py +0 -3
  56. web3/_utils/module_testing/eth_module.py +695 -643
  57. web3/_utils/module_testing/module_testing_utils.py +61 -34
  58. web3/_utils/module_testing/persistent_connection_provider.py +56 -25
  59. web3/_utils/module_testing/utils.py +258 -0
  60. web3/_utils/module_testing/web3_module.py +438 -17
  61. web3/_utils/normalizers.py +13 -11
  62. web3/_utils/rpc_abi.py +5 -32
  63. web3/_utils/threads.py +8 -7
  64. web3/_utils/transactions.py +14 -12
  65. web3/_utils/type_conversion.py +5 -1
  66. web3/_utils/validation.py +17 -17
  67. web3/auto/gethdev.py +7 -2
  68. web3/beacon/__init__.py +6 -1
  69. web3/beacon/async_beacon.py +9 -5
  70. web3/beacon/{main.py → beacon.py} +7 -5
  71. web3/contract/__init__.py +7 -0
  72. web3/contract/async_contract.py +47 -46
  73. web3/contract/base_contract.py +183 -158
  74. web3/contract/contract.py +49 -43
  75. web3/contract/utils.py +203 -59
  76. web3/datastructures.py +79 -31
  77. web3/eth/__init__.py +7 -0
  78. web3/eth/async_eth.py +39 -51
  79. web3/eth/base_eth.py +17 -10
  80. web3/eth/eth.py +30 -68
  81. web3/exceptions.py +108 -82
  82. web3/gas_strategies/time_based.py +8 -6
  83. web3/geth.py +1 -254
  84. web3/main.py +75 -122
  85. web3/manager.py +316 -146
  86. web3/method.py +38 -31
  87. web3/middleware/__init__.py +67 -89
  88. web3/middleware/attrdict.py +36 -49
  89. web3/middleware/base.py +174 -0
  90. web3/middleware/buffered_gas_estimate.py +20 -21
  91. web3/middleware/filter.py +157 -117
  92. web3/middleware/formatting.py +124 -108
  93. web3/middleware/gas_price_strategy.py +20 -32
  94. web3/middleware/names.py +29 -26
  95. web3/middleware/proof_of_authority.py +68 -0
  96. web3/middleware/pythonic.py +2 -2
  97. web3/middleware/signing.py +74 -89
  98. web3/middleware/stalecheck.py +52 -79
  99. web3/middleware/validation.py +5 -13
  100. web3/module.py +54 -10
  101. web3/providers/__init__.py +10 -6
  102. web3/providers/async_base.py +117 -39
  103. web3/providers/auto.py +3 -3
  104. web3/providers/base.py +89 -33
  105. web3/providers/eth_tester/__init__.py +5 -0
  106. web3/providers/eth_tester/defaults.py +1 -64
  107. web3/providers/eth_tester/main.py +99 -31
  108. web3/providers/eth_tester/middleware.py +45 -73
  109. web3/providers/ipc.py +42 -46
  110. web3/providers/{websocket/websocket.py → legacy_websocket.py} +32 -7
  111. web3/providers/persistent/__init__.py +22 -0
  112. web3/providers/persistent/async_ipc.py +153 -0
  113. web3/providers/{persistent.py → persistent/persistent.py} +106 -25
  114. web3/providers/persistent/persistent_connection.py +84 -0
  115. web3/providers/{websocket → persistent}/request_processor.py +94 -32
  116. web3/providers/persistent/utils.py +43 -0
  117. web3/providers/{websocket/websocket_v2.py → persistent/websocket.py} +29 -28
  118. web3/providers/rpc/__init__.py +11 -0
  119. web3/providers/rpc/async_rpc.py +171 -0
  120. web3/providers/rpc/rpc.py +179 -0
  121. web3/providers/rpc/utils.py +92 -0
  122. web3/testing.py +4 -4
  123. web3/tools/benchmark/main.py +22 -22
  124. web3/tools/benchmark/node.py +2 -8
  125. web3/tools/benchmark/reporting.py +2 -2
  126. web3/tools/benchmark/utils.py +1 -1
  127. web3/tracing.py +9 -5
  128. web3/types.py +30 -107
  129. web3/utils/__init__.py +58 -5
  130. web3/utils/abi.py +575 -10
  131. web3/utils/async_exception_handling.py +19 -7
  132. web3/utils/caching.py +32 -13
  133. web3/utils/exception_handling.py +7 -5
  134. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/LICENSE +1 -1
  135. web3-7.0.0.dist-info/METADATA +112 -0
  136. web3-7.0.0.dist-info/RECORD +167 -0
  137. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/WHEEL +1 -1
  138. {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/top_level.txt +0 -1
  139. ethpm/__init__.py +0 -20
  140. ethpm/_utils/__init__.py +0 -0
  141. ethpm/_utils/backend.py +0 -93
  142. ethpm/_utils/cache.py +0 -44
  143. ethpm/_utils/chains.py +0 -119
  144. ethpm/_utils/contract.py +0 -35
  145. ethpm/_utils/deployments.py +0 -145
  146. ethpm/_utils/ipfs.py +0 -116
  147. ethpm/_utils/protobuf/__init__.py +0 -0
  148. ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
  149. ethpm/_utils/registry.py +0 -29
  150. ethpm/assets/__init__.py +0 -0
  151. ethpm/assets/ens/v3.json +0 -1
  152. ethpm/assets/escrow/with_bytecode_v3.json +0 -1
  153. ethpm/assets/ipfs_file.proto +0 -32
  154. ethpm/assets/owned/output_v3.json +0 -1
  155. ethpm/assets/owned/with_contract_type_v3.json +0 -1
  156. ethpm/assets/registry/contracts/Authority.sol +0 -156
  157. ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
  158. ethpm/assets/registry/contracts/PackageDB.sol +0 -225
  159. ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
  160. ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
  161. ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
  162. ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
  163. ethpm/assets/registry/solc_input.json +0 -1
  164. ethpm/assets/registry/solc_output.json +0 -1
  165. ethpm/assets/registry/v3.json +0 -1
  166. ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
  167. ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
  168. ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
  169. ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
  170. ethpm/assets/simple-registry/solc_input.json +0 -33
  171. ethpm/assets/simple-registry/solc_output.json +0 -1
  172. ethpm/assets/simple-registry/v3.json +0 -1
  173. ethpm/assets/standard-token/output_v3.json +0 -1
  174. ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
  175. ethpm/assets/vyper_registry/0.1.0.json +0 -1
  176. ethpm/assets/vyper_registry/registry.vy +0 -216
  177. ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
  178. ethpm/backends/__init__.py +0 -0
  179. ethpm/backends/base.py +0 -43
  180. ethpm/backends/http.py +0 -108
  181. ethpm/backends/ipfs.py +0 -219
  182. ethpm/backends/registry.py +0 -154
  183. ethpm/constants.py +0 -17
  184. ethpm/contract.py +0 -187
  185. ethpm/dependencies.py +0 -58
  186. ethpm/deployments.py +0 -80
  187. ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
  188. ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
  189. ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
  190. ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
  191. ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
  192. ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
  193. ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
  194. ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
  195. ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
  196. ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
  197. ethpm/ethpm-spec/examples/owned/v3.json +0 -1
  198. ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
  199. ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
  200. ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
  201. ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
  202. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
  203. ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
  204. ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
  205. ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
  206. ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
  207. ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
  208. ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
  209. ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
  210. ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
  211. ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
  212. ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
  213. ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
  214. ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
  215. ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
  216. ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
  217. ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
  218. ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
  219. ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
  220. ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
  221. ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
  222. ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
  223. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
  224. ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
  225. ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
  226. ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
  227. ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
  228. ethpm/ethpm-spec/spec/package.spec.json +0 -379
  229. ethpm/ethpm-spec/spec/v3.spec.json +0 -483
  230. ethpm/exceptions.py +0 -68
  231. ethpm/package.py +0 -438
  232. ethpm/tools/__init__.py +0 -4
  233. ethpm/tools/builder.py +0 -930
  234. ethpm/tools/checker.py +0 -312
  235. ethpm/tools/get_manifest.py +0 -19
  236. ethpm/uri.py +0 -141
  237. ethpm/validation/__init__.py +0 -0
  238. ethpm/validation/manifest.py +0 -146
  239. ethpm/validation/misc.py +0 -39
  240. ethpm/validation/package.py +0 -80
  241. ethpm/validation/uri.py +0 -163
  242. web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
  243. web3/_utils/miner.py +0 -88
  244. web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
  245. web3/_utils/request.py +0 -265
  246. web3/middleware/abi.py +0 -11
  247. web3/middleware/async_cache.py +0 -99
  248. web3/middleware/cache.py +0 -374
  249. web3/middleware/exception_handling.py +0 -49
  250. web3/middleware/exception_retry_request.py +0 -188
  251. web3/middleware/fixture.py +0 -190
  252. web3/middleware/geth_poa.py +0 -81
  253. web3/middleware/normalize_request_parameters.py +0 -11
  254. web3/middleware/simulate_unmined_transaction.py +0 -43
  255. web3/pm.py +0 -602
  256. web3/providers/async_rpc.py +0 -99
  257. web3/providers/rpc.py +0 -98
  258. web3/providers/websocket/__init__.py +0 -11
  259. web3/providers/websocket/websocket_connection.py +0 -42
  260. web3/tools/__init__.py +0 -4
  261. web3/tools/pytest_ethereum/__init__.py +0 -0
  262. web3/tools/pytest_ethereum/_utils.py +0 -145
  263. web3/tools/pytest_ethereum/deployer.py +0 -48
  264. web3/tools/pytest_ethereum/exceptions.py +0 -22
  265. web3/tools/pytest_ethereum/linker.py +0 -128
  266. web3/tools/pytest_ethereum/plugins.py +0 -33
  267. web3-6.20.2.dist-info/METADATA +0 -103
  268. web3-6.20.2.dist-info/RECORD +0 -283
  269. web3-6.20.2.dist-info/entry_points.txt +0 -2
  270. /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
@@ -3,7 +3,9 @@ from typing import (
3
3
  Any,
4
4
  Callable,
5
5
  Coroutine,
6
+ Literal,
6
7
  Optional,
8
+ Union,
7
9
  cast,
8
10
  )
9
11
 
@@ -13,14 +15,16 @@ from eth_utils.toolz import (
13
15
  merge,
14
16
  )
15
17
 
18
+ from web3.exceptions import (
19
+ Web3ValueError,
20
+ )
21
+ from web3.middleware.base import (
22
+ Web3MiddlewareBuilder,
23
+ )
16
24
  from web3.types import (
17
- AsyncMiddleware,
18
- AsyncMiddlewareCoroutine,
19
25
  EthSubscriptionParams,
20
26
  Formatters,
21
27
  FormattersDict,
22
- Literal,
23
- Middleware,
24
28
  RPCEndpoint,
25
29
  RPCResponse,
26
30
  )
@@ -30,6 +34,9 @@ if TYPE_CHECKING:
30
34
  AsyncWeb3,
31
35
  Web3,
32
36
  )
37
+ from web3.middleware.base import ( # noqa: F401
38
+ Web3Middleware,
39
+ )
33
40
  from web3.providers import ( # noqa: F401
34
41
  PersistentConnectionProvider,
35
42
  )
@@ -85,125 +92,134 @@ def _apply_response_formatters(
85
92
  return response
86
93
 
87
94
 
88
- # --- sync -- #
89
-
90
-
91
- def construct_formatting_middleware(
92
- request_formatters: Optional[Formatters] = None,
93
- result_formatters: Optional[Formatters] = None,
94
- error_formatters: Optional[Formatters] = None,
95
- ) -> Middleware:
96
- def ignore_web3_in_standard_formatters(
97
- _w3: "Web3",
98
- _method: RPCEndpoint,
99
- ) -> FormattersDict:
100
- return dict(
101
- request_formatters=request_formatters or {},
102
- result_formatters=result_formatters or {},
103
- error_formatters=error_formatters or {},
104
- )
95
+ SYNC_FORMATTERS_BUILDER = Callable[["Web3", RPCEndpoint], FormattersDict]
96
+ ASYNC_FORMATTERS_BUILDER = Callable[
97
+ ["AsyncWeb3", RPCEndpoint], Coroutine[Any, Any, FormattersDict]
98
+ ]
99
+
100
+
101
+ class FormattingMiddlewareBuilder(Web3MiddlewareBuilder):
102
+ request_formatters: Formatters = None
103
+ result_formatters: Formatters = None
104
+ error_formatters: Formatters = None
105
+ sync_formatters_builder: SYNC_FORMATTERS_BUILDER = None
106
+ async_formatters_builder: ASYNC_FORMATTERS_BUILDER = None
107
+
108
+ @staticmethod
109
+ @curry
110
+ def build(
111
+ w3: Union["AsyncWeb3", "Web3"],
112
+ # formatters option:
113
+ request_formatters: Optional[Formatters] = None,
114
+ result_formatters: Optional[Formatters] = None,
115
+ error_formatters: Optional[Formatters] = None,
116
+ # formatters builder option:
117
+ sync_formatters_builder: Optional[SYNC_FORMATTERS_BUILDER] = None,
118
+ async_formatters_builder: Optional[ASYNC_FORMATTERS_BUILDER] = None,
119
+ ) -> "FormattingMiddlewareBuilder":
120
+ # if not both sync and async formatters are specified, raise error
121
+ if (
122
+ sync_formatters_builder is None and async_formatters_builder is not None
123
+ ) or (sync_formatters_builder is not None and async_formatters_builder is None):
124
+ raise Web3ValueError(
125
+ "Must specify both sync_formatters_builder and async_formatters_builder"
126
+ )
105
127
 
106
- return construct_web3_formatting_middleware(ignore_web3_in_standard_formatters)
128
+ if sync_formatters_builder is not None and async_formatters_builder is not None:
129
+ if (
130
+ request_formatters is not None
131
+ or result_formatters is not None
132
+ or error_formatters is not None
133
+ ):
134
+ raise Web3ValueError(
135
+ "Cannot specify formatters_builder and formatters at the same time"
136
+ )
107
137
 
138
+ middleware = FormattingMiddlewareBuilder(w3)
139
+ middleware.request_formatters = request_formatters or {}
140
+ middleware.result_formatters = result_formatters or {}
141
+ middleware.error_formatters = error_formatters or {}
142
+ middleware.sync_formatters_builder = sync_formatters_builder
143
+ middleware.async_formatters_builder = async_formatters_builder
144
+ return middleware
108
145
 
109
- def construct_web3_formatting_middleware(
110
- web3_formatters_builder: Callable[["Web3", RPCEndpoint], FormattersDict],
111
- ) -> Middleware:
112
- def formatter_middleware(
113
- make_request: Callable[[RPCEndpoint, Any], Any],
114
- w3: "Web3",
115
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
116
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
146
+ def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
147
+ if self.sync_formatters_builder is not None:
117
148
  formatters = merge(
118
149
  FORMATTER_DEFAULTS,
119
- web3_formatters_builder(w3, method),
150
+ self.sync_formatters_builder(cast("Web3", self._w3), method),
120
151
  )
121
- request_formatters = formatters.pop("request_formatters")
152
+ self.request_formatters = formatters.pop("request_formatters")
122
153
 
123
- if method in request_formatters:
124
- formatter = request_formatters[method]
125
- params = formatter(params)
126
- response = make_request(method, params)
154
+ if method in self.request_formatters:
155
+ formatter = self.request_formatters[method]
156
+ params = formatter(params)
127
157
 
128
- return _apply_response_formatters(
129
- method,
130
- formatters["result_formatters"],
131
- formatters["error_formatters"],
132
- response,
133
- )
134
-
135
- return middleware
158
+ return method, params
136
159
 
137
- return formatter_middleware
138
-
139
-
140
- # --- async --- #
160
+ def response_processor(self, method: RPCEndpoint, response: "RPCResponse") -> Any:
161
+ if self.sync_formatters_builder is not None:
162
+ formatters = merge(
163
+ FORMATTER_DEFAULTS,
164
+ self.sync_formatters_builder(cast("Web3", self._w3), method),
165
+ )
166
+ self.result_formatters = formatters["result_formatters"]
167
+ self.error_formatters = formatters["error_formatters"]
168
+
169
+ return _apply_response_formatters(
170
+ method,
171
+ self.result_formatters,
172
+ self.error_formatters,
173
+ response,
174
+ )
141
175
 
176
+ # -- async -- #
142
177
 
143
- async def async_construct_formatting_middleware(
144
- request_formatters: Optional[Formatters] = None,
145
- result_formatters: Optional[Formatters] = None,
146
- error_formatters: Optional[Formatters] = None,
147
- ) -> AsyncMiddleware:
148
- async def ignore_web3_in_standard_formatters(
149
- _async_w3: "AsyncWeb3",
150
- _method: RPCEndpoint,
151
- ) -> FormattersDict:
152
- return dict(
153
- request_formatters=request_formatters or {},
154
- result_formatters=result_formatters or {},
155
- error_formatters=error_formatters or {},
156
- )
178
+ async def async_request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
179
+ if self.async_formatters_builder is not None:
180
+ formatters = merge(
181
+ FORMATTER_DEFAULTS,
182
+ await self.async_formatters_builder(
183
+ cast("AsyncWeb3", self._w3), method
184
+ ),
185
+ )
186
+ self.request_formatters = formatters.pop("request_formatters")
157
187
 
158
- return await async_construct_web3_formatting_middleware(
159
- ignore_web3_in_standard_formatters
160
- )
188
+ if method in self.request_formatters:
189
+ formatter = self.request_formatters[method]
190
+ params = formatter(params)
161
191
 
192
+ return method, params
162
193
 
163
- async def async_construct_web3_formatting_middleware(
164
- async_web3_formatters_builder: Callable[
165
- ["AsyncWeb3", RPCEndpoint], Coroutine[Any, Any, FormattersDict]
166
- ]
167
- ) -> Callable[
168
- [Callable[[RPCEndpoint, Any], Any], "AsyncWeb3"],
169
- Coroutine[Any, Any, AsyncMiddlewareCoroutine],
170
- ]:
171
- async def formatter_middleware(
172
- make_request: Callable[[RPCEndpoint, Any], Any],
173
- async_w3: "AsyncWeb3",
174
- ) -> AsyncMiddlewareCoroutine:
175
- async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
194
+ async def async_response_processor(
195
+ self, method: RPCEndpoint, response: "RPCResponse"
196
+ ) -> Any:
197
+ if self.async_formatters_builder is not None:
176
198
  formatters = merge(
177
199
  FORMATTER_DEFAULTS,
178
- await async_web3_formatters_builder(async_w3, method),
200
+ await self.async_formatters_builder(
201
+ cast("AsyncWeb3", self._w3), method
202
+ ),
179
203
  )
180
- request_formatters = formatters.pop("request_formatters")
181
-
182
- if method in request_formatters:
183
- formatter = request_formatters[method]
184
- params = formatter(params)
185
- response = await make_request(method, params)
186
-
187
- if async_w3.provider.has_persistent_connection:
188
- # asynchronous response processing
189
- provider = cast("PersistentConnectionProvider", async_w3.provider)
190
- provider._request_processor.append_middleware_response_processor(
191
- response,
192
- _apply_response_formatters(
193
- method,
194
- formatters["result_formatters"],
195
- formatters["error_formatters"],
196
- ),
197
- )
198
- return response
199
- else:
200
- return _apply_response_formatters(
201
- method,
202
- formatters["result_formatters"],
203
- formatters["error_formatters"],
204
- response,
205
- )
204
+ self.result_formatters = formatters["result_formatters"]
205
+ self.error_formatters = formatters["error_formatters"]
206
206
 
207
- return middleware
208
-
209
- return formatter_middleware
207
+ if self._w3.provider.has_persistent_connection:
208
+ # asynchronous response processing
209
+ provider = cast("PersistentConnectionProvider", self._w3.provider)
210
+ provider._request_processor.append_middleware_response_processor(
211
+ response,
212
+ _apply_response_formatters(
213
+ method,
214
+ self.result_formatters,
215
+ self.error_formatters,
216
+ ),
217
+ )
218
+ return response
219
+ else:
220
+ return _apply_response_formatters(
221
+ method,
222
+ self.result_formatters,
223
+ self.error_formatters,
224
+ response,
225
+ )
@@ -1,7 +1,7 @@
1
1
  from typing import (
2
2
  TYPE_CHECKING,
3
3
  Any,
4
- Callable,
4
+ cast,
5
5
  )
6
6
 
7
7
  from eth_utils.toolz import (
@@ -23,11 +23,12 @@ from web3.exceptions import (
23
23
  InvalidTransaction,
24
24
  TransactionTypeMismatch,
25
25
  )
26
+ from web3.middleware.base import (
27
+ Web3Middleware,
28
+ )
26
29
  from web3.types import (
27
- AsyncMiddlewareCoroutine,
28
30
  BlockData,
29
31
  RPCEndpoint,
30
- RPCResponse,
31
32
  TxParams,
32
33
  Wei,
33
34
  )
@@ -78,51 +79,38 @@ def validate_transaction_params(
78
79
  return transaction
79
80
 
80
81
 
81
- def gas_price_strategy_middleware(
82
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
83
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
82
+ class GasPriceStrategyMiddleware(Web3Middleware):
84
83
  """
85
- - Uses a gas price strategy if one is set. This is only supported
86
- for legacy transactions. It is recommended to send dynamic fee
87
- transactions (EIP-1559) whenever possible.
84
+ - Uses a gas price strategy if one is set. This is only supported for
85
+ legacy transactions. It is recommended to send dynamic fee transactions
86
+ (EIP-1559) whenever possible.
88
87
 
89
88
  - Validates transaction params against legacy and dynamic fee txn values.
90
89
  """
91
90
 
92
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
91
+ def request_processor(self, method: RPCEndpoint, params: Any) -> Any:
93
92
  if method == "eth_sendTransaction":
94
93
  transaction = params[0]
95
- generated_gas_price = w3.eth.generate_gas_price(transaction)
94
+ generated_gas_price = self._w3.eth.generate_gas_price(transaction)
95
+ w3 = cast("Web3", self._w3)
96
96
  latest_block = w3.eth.get_block("latest")
97
97
  transaction = validate_transaction_params(
98
98
  transaction, latest_block, generated_gas_price
99
99
  )
100
- return make_request(method, (transaction,))
101
- return make_request(method, params)
100
+ params = (transaction,)
102
101
 
103
- return middleware
102
+ return method, params
104
103
 
104
+ # -- async -- #
105
105
 
106
- async def async_gas_price_strategy_middleware(
107
- make_request: Callable[[RPCEndpoint, Any], Any], async_w3: "AsyncWeb3"
108
- ) -> AsyncMiddlewareCoroutine:
109
- """
110
- - Uses a gas price strategy if one is set. This is only supported for
111
- legacy transactions. It is recommended to send dynamic fee transactions
112
- (EIP-1559) whenever possible.
113
-
114
- - Validates transaction params against legacy and dynamic fee txn values.
115
- """
116
-
117
- async def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
106
+ async def async_request_processor(self, method: RPCEndpoint, params: Any) -> Any:
118
107
  if method == "eth_sendTransaction":
119
108
  transaction = params[0]
120
- generated_gas_price = async_w3.eth.generate_gas_price(transaction)
121
- latest_block = await async_w3.eth.get_block("latest")
109
+ w3 = cast("AsyncWeb3", self._w3)
110
+ generated_gas_price = w3.eth.generate_gas_price(transaction)
111
+ latest_block = await w3.eth.get_block("latest")
122
112
  transaction = validate_transaction_params(
123
113
  transaction, latest_block, generated_gas_price
124
114
  )
125
- return await make_request(method, (transaction,))
126
- return await make_request(method, params)
127
-
128
- return middleware
115
+ params = (transaction,)
116
+ return method, params
web3/middleware/names.py CHANGED
@@ -1,10 +1,10 @@
1
1
  from typing import (
2
2
  TYPE_CHECKING,
3
3
  Any,
4
- Callable,
5
4
  Dict,
6
5
  Sequence,
7
6
  Union,
7
+ cast,
8
8
  )
9
9
 
10
10
  from toolz import (
@@ -20,8 +20,6 @@ from web3._utils.rpc_abi import (
20
20
  abi_request_formatters,
21
21
  )
22
22
  from web3.types import (
23
- AsyncMiddlewareCoroutine,
24
- Middleware,
25
23
  RPCEndpoint,
26
24
  )
27
25
 
@@ -33,8 +31,14 @@ from .._utils.abi import (
33
31
  from .._utils.formatters import (
34
32
  recursive_map,
35
33
  )
34
+ from ..exceptions import (
35
+ Web3TypeError,
36
+ )
37
+ from .base import (
38
+ Web3Middleware,
39
+ )
36
40
  from .formatting import (
37
- construct_formatting_middleware,
41
+ FormattingMiddlewareBuilder,
38
42
  )
39
43
 
40
44
  if TYPE_CHECKING:
@@ -44,18 +48,6 @@ if TYPE_CHECKING:
44
48
  )
45
49
 
46
50
 
47
- def name_to_address_middleware(w3: "Web3") -> Middleware:
48
- normalizers = [
49
- abi_ens_resolver(w3),
50
- ]
51
- return construct_formatting_middleware(
52
- request_formatters=abi_request_formatters(normalizers, RPC_ABIS)
53
- )
54
-
55
-
56
- # -- async -- #
57
-
58
-
59
51
  def _is_logs_subscription_with_optional_args(method: RPCEndpoint, params: Any) -> bool:
60
52
  return method == "eth_subscribe" and len(params) == 2 and params[0] == "logs"
61
53
 
@@ -103,17 +95,29 @@ async def async_apply_ens_to_address_conversion(
103
95
  return (formatted_params_dict, *params[1:])
104
96
 
105
97
  else:
106
- raise TypeError(
98
+ raise Web3TypeError(
107
99
  f"ABI definitions must be a list or dictionary, "
108
100
  f"got {abi_types_for_method!r}"
109
101
  )
110
102
 
111
103
 
112
- async def async_name_to_address_middleware(
113
- make_request: Callable[[RPCEndpoint, Any], Any],
114
- async_w3: "AsyncWeb3",
115
- ) -> AsyncMiddlewareCoroutine:
116
- async def middleware(method: RPCEndpoint, params: Any) -> Any:
104
+ class ENSNameToAddressMiddleware(Web3Middleware):
105
+ _formatting_middleware = None
106
+
107
+ def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
108
+ if self._formatting_middleware is None:
109
+ normalizers = [
110
+ abi_ens_resolver(self._w3),
111
+ ]
112
+ self._formatting_middleware = FormattingMiddlewareBuilder.build(
113
+ request_formatters=abi_request_formatters(normalizers, RPC_ABIS)
114
+ )
115
+
116
+ return self._formatting_middleware(self._w3).request_processor(method, params)
117
+
118
+ # -- async -- #
119
+
120
+ async def async_request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
117
121
  abi_types_for_method = RPC_ABIS.get(method, None)
118
122
 
119
123
  if abi_types_for_method is not None:
@@ -121,7 +125,7 @@ async def async_name_to_address_middleware(
121
125
  # eth_subscribe optional logs params are unique.
122
126
  # Handle them separately here.
123
127
  (formatted_dict,) = await async_apply_ens_to_address_conversion(
124
- async_w3,
128
+ cast("AsyncWeb3", self._w3),
125
129
  (params[1],),
126
130
  {
127
131
  "address": "address",
@@ -132,10 +136,9 @@ async def async_name_to_address_middleware(
132
136
 
133
137
  else:
134
138
  params = await async_apply_ens_to_address_conversion(
135
- async_w3,
139
+ cast("AsyncWeb3", self._w3),
136
140
  params,
137
141
  abi_types_for_method,
138
142
  )
139
- return await make_request(method, params)
140
143
 
141
- return middleware
144
+ return method, params
@@ -0,0 +1,68 @@
1
+ from typing import (
2
+ TYPE_CHECKING,
3
+ )
4
+
5
+ from eth_utils import (
6
+ is_dict,
7
+ )
8
+ from eth_utils.curried import (
9
+ apply_formatter_if,
10
+ apply_formatters_to_dict,
11
+ apply_key_map,
12
+ is_null,
13
+ )
14
+ from eth_utils.toolz import (
15
+ complement,
16
+ compose,
17
+ )
18
+ from hexbytes import (
19
+ HexBytes,
20
+ )
21
+
22
+ from web3._utils.rpc_abi import (
23
+ RPC,
24
+ )
25
+ from web3.middleware.formatting import (
26
+ FormattingMiddlewareBuilder,
27
+ )
28
+
29
+ if TYPE_CHECKING:
30
+ from web3 import ( # noqa: F401
31
+ AsyncWeb3,
32
+ Web3,
33
+ )
34
+
35
+ is_not_null = complement(is_null)
36
+
37
+ remap_extradata_to_poa_fields = apply_key_map(
38
+ {
39
+ "extraData": "proofOfAuthorityData",
40
+ }
41
+ )
42
+
43
+ pythonic_extradata_to_poa = apply_formatters_to_dict(
44
+ {
45
+ "proofOfAuthorityData": HexBytes,
46
+ }
47
+ )
48
+
49
+ extradata_to_poa_cleanup = compose(
50
+ pythonic_extradata_to_poa, remap_extradata_to_poa_fields
51
+ )
52
+
53
+
54
+ ExtraDataToPOAMiddleware = FormattingMiddlewareBuilder.build(
55
+ result_formatters={
56
+ RPC.eth_getBlockByHash: apply_formatter_if(
57
+ is_not_null, extradata_to_poa_cleanup
58
+ ),
59
+ RPC.eth_getBlockByNumber: apply_formatter_if(
60
+ is_not_null, extradata_to_poa_cleanup
61
+ ),
62
+ RPC.eth_subscribe: apply_formatter_if(
63
+ is_not_null,
64
+ # original call to eth_subscribe returns a string, needs a dict check
65
+ apply_formatter_if(is_dict, extradata_to_poa_cleanup),
66
+ ),
67
+ },
68
+ )
@@ -3,10 +3,10 @@ from web3._utils.method_formatters import (
3
3
  PYTHONIC_RESULT_FORMATTERS,
4
4
  )
5
5
  from web3.middleware.formatting import (
6
- construct_formatting_middleware,
6
+ FormattingMiddlewareBuilder,
7
7
  )
8
8
 
9
- pythonic_middleware = construct_formatting_middleware(
9
+ PythonicMiddleware = FormattingMiddlewareBuilder.build(
10
10
  request_formatters=PYTHONIC_REQUEST_FORMATTERS,
11
11
  result_formatters=PYTHONIC_RESULT_FORMATTERS,
12
12
  )