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
@@ -5,12 +5,12 @@ import operator
5
5
  from typing import (
6
6
  TYPE_CHECKING,
7
7
  Any,
8
- Callable,
9
8
  Collection,
10
9
  Iterable,
11
10
  Tuple,
12
11
  TypeVar,
13
12
  Union,
13
+ cast,
14
14
  )
15
15
 
16
16
  from eth_account import (
@@ -19,6 +19,9 @@ from eth_account import (
19
19
  from eth_account.signers.local import (
20
20
  LocalAccount,
21
21
  )
22
+ from eth_account.types import (
23
+ TransactionDictType as EthAccountTxParams,
24
+ )
22
25
  from eth_keys.datatypes import (
23
26
  PrivateKey,
24
27
  )
@@ -36,6 +39,9 @@ from eth_utils.curried import (
36
39
  from eth_utils.toolz import (
37
40
  compose,
38
41
  )
42
+ from toolz import (
43
+ curry,
44
+ )
39
45
 
40
46
  from web3._utils.async_transactions import (
41
47
  async_fill_nonce,
@@ -52,12 +58,14 @@ from web3._utils.transactions import (
52
58
  fill_nonce,
53
59
  fill_transaction_defaults,
54
60
  )
61
+ from web3.exceptions import (
62
+ Web3TypeError,
63
+ )
64
+ from web3.middleware.base import (
65
+ Web3MiddlewareBuilder,
66
+ )
55
67
  from web3.types import (
56
- AsyncMiddleware,
57
- AsyncMiddlewareCoroutine,
58
- Middleware,
59
68
  RPCEndpoint,
60
- RPCResponse,
61
69
  TxParams,
62
70
  )
63
71
 
@@ -106,7 +114,7 @@ def gen_normalized_accounts(
106
114
 
107
115
  @singledispatch
108
116
  def to_account(val: Any) -> LocalAccount:
109
- raise TypeError(
117
+ raise Web3TypeError(
110
118
  "key must be one of the types: "
111
119
  "eth_keys.datatype.PrivateKey, eth_account.signers.local.LocalAccount, "
112
120
  "or raw private key as a hex string or byte string. "
@@ -130,7 +138,8 @@ to_account.register(bytes, private_key_to_account)
130
138
 
131
139
 
132
140
  def format_transaction(transaction: TxParams) -> TxParams:
133
- """Format transaction so that it can be used correctly in the signing middleware.
141
+ """
142
+ Format transaction so that it can be used correctly in the signing middleware.
134
143
 
135
144
  Converts bytes to hex strings and other types that can be passed to
136
145
  the underlying layers. Also has the effect of normalizing 'from' for
@@ -141,99 +150,75 @@ def format_transaction(transaction: TxParams) -> TxParams:
141
150
  )
142
151
 
143
152
 
144
- def construct_sign_and_send_raw_middleware(
145
- private_key_or_account: Union[_PrivateKey, Collection[_PrivateKey]]
146
- ) -> Middleware:
147
- """Capture transactions sign and send as raw transactions
148
-
149
-
150
- Keyword arguments:
151
- private_key_or_account -- A single private key or a tuple,
152
- list or set of private keys. Keys can be any of the following formats:
153
- - An eth_account.LocalAccount object
154
- - An eth_keys.PrivateKey object
155
- - A raw private key as a hex string or byte string
156
- """
157
-
158
- accounts = gen_normalized_accounts(private_key_or_account)
159
-
160
- def sign_and_send_raw_middleware(
161
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
162
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
163
- format_and_fill_tx = compose(
164
- format_transaction, fill_transaction_defaults(w3), fill_nonce(w3)
165
- )
166
-
167
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
168
- if method != "eth_sendTransaction":
169
- return make_request(method, params)
170
- else:
171
- transaction = format_and_fill_tx(params[0])
172
-
173
- if "from" not in transaction:
174
- return make_request(method, params)
175
- elif transaction.get("from") not in accounts:
176
- return make_request(method, params)
177
-
178
- account = accounts[transaction["from"]]
179
- raw_tx = account.sign_transaction(transaction).rawTransaction
180
-
181
- return make_request(RPCEndpoint("eth_sendRawTransaction"), [raw_tx.hex()])
153
+ class SignAndSendRawMiddlewareBuilder(Web3MiddlewareBuilder):
154
+ _accounts = None
155
+ format_and_fill_tx = None
182
156
 
157
+ @staticmethod
158
+ @curry
159
+ def build(
160
+ private_key_or_account: Union[_PrivateKey, Collection[_PrivateKey]],
161
+ w3: Union["Web3", "AsyncWeb3"],
162
+ ) -> "SignAndSendRawMiddlewareBuilder":
163
+ middleware = SignAndSendRawMiddlewareBuilder(w3)
164
+ middleware._accounts = gen_normalized_accounts(private_key_or_account)
183
165
  return middleware
184
166
 
185
- return sign_and_send_raw_middleware
167
+ def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
168
+ if method != "eth_sendTransaction":
169
+ return method, params
170
+ else:
171
+ w3 = cast("Web3", self._w3)
172
+ if self.format_and_fill_tx is None:
173
+ self.format_and_fill_tx = compose(
174
+ format_transaction,
175
+ fill_transaction_defaults(w3),
176
+ fill_nonce(w3),
177
+ )
178
+
179
+ filled_transaction = self.format_and_fill_tx(params[0])
180
+ tx_from = filled_transaction.get("from", None)
186
181
 
182
+ if tx_from is None or (
183
+ tx_from is not None and tx_from not in self._accounts
184
+ ):
185
+ return method, params
186
+ else:
187
+ account = self._accounts[to_checksum_address(tx_from)]
188
+ raw_tx = account.sign_transaction(filled_transaction).raw_transaction
187
189
 
188
- # -- async -- #
190
+ return (
191
+ RPCEndpoint("eth_sendRawTransaction"),
192
+ [raw_tx.hex()],
193
+ )
189
194
 
195
+ # -- async -- #
190
196
 
191
- async def async_construct_sign_and_send_raw_middleware(
192
- private_key_or_account: Union[_PrivateKey, Collection[_PrivateKey]]
193
- ) -> AsyncMiddleware:
194
- """
195
- Capture transactions & sign and send as raw transactions
196
-
197
- Keyword arguments:
198
- private_key_or_account -- A single private key or a tuple,
199
- list or set of private keys. Keys can be any of the following formats:
200
- - An eth_account.LocalAccount object
201
- - An eth_keys.PrivateKey object
202
- - A raw private key as a hex string or byte string
203
- """
204
- accounts = gen_normalized_accounts(private_key_or_account)
197
+ async def async_request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
198
+ if method != "eth_sendTransaction":
199
+ return method, params
205
200
 
206
- async def async_sign_and_send_raw_middleware(
207
- make_request: Callable[[RPCEndpoint, Any], Any], async_w3: "AsyncWeb3"
208
- ) -> AsyncMiddlewareCoroutine:
209
- async def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
210
- if method != "eth_sendTransaction":
211
- # quick exit if not `eth_sendTransaction`
212
- return await make_request(method, params)
201
+ else:
202
+ w3 = cast("AsyncWeb3", self._w3)
213
203
 
214
204
  formatted_transaction = format_transaction(params[0])
215
205
  filled_transaction = await async_fill_transaction_defaults(
216
- async_w3,
217
- formatted_transaction,
218
- )
219
- filled_transaction = await async_fill_nonce(
220
- async_w3,
221
- filled_transaction,
206
+ w3, formatted_transaction
222
207
  )
223
-
208
+ filled_transaction = await async_fill_nonce(w3, filled_transaction)
224
209
  tx_from = filled_transaction.get("from", None)
225
210
 
226
- if tx_from is None or (tx_from is not None and tx_from not in accounts):
227
- return await make_request(method, params)
228
-
229
- account = accounts[to_checksum_address(tx_from)]
230
- raw_tx = account.sign_transaction(filled_transaction).rawTransaction
231
-
232
- return await make_request(
233
- RPCEndpoint("eth_sendRawTransaction"),
234
- [raw_tx.hex()],
235
- )
236
-
237
- return middleware
238
-
239
- return async_sign_and_send_raw_middleware
211
+ if tx_from is None or (
212
+ tx_from is not None and tx_from not in self._accounts
213
+ ):
214
+ return method, params
215
+ else:
216
+ account = self._accounts[to_checksum_address(tx_from)]
217
+ raw_tx = account.sign_transaction(
218
+ cast(EthAccountTxParams, filled_transaction)
219
+ ).raw_transaction
220
+
221
+ return (
222
+ RPCEndpoint("eth_sendRawTransaction"),
223
+ [raw_tx.hex()],
224
+ )
@@ -6,18 +6,25 @@ from typing import ( # noqa: F401
6
6
  Collection,
7
7
  Dict,
8
8
  Optional,
9
+ Union,
10
+ cast,
11
+ )
12
+
13
+ from toolz import (
14
+ curry,
9
15
  )
10
16
 
11
17
  from web3.exceptions import (
12
18
  StaleBlockchain,
19
+ Web3ValueError,
20
+ )
21
+ from web3.middleware.base import (
22
+ Web3Middleware,
23
+ Web3MiddlewareBuilder,
13
24
  )
14
25
  from web3.types import (
15
- AsyncMiddleware,
16
- AsyncMiddlewareCoroutine,
17
26
  BlockData,
18
- Middleware,
19
27
  RPCEndpoint,
20
- RPCResponse,
21
28
  )
22
29
 
23
30
  if TYPE_CHECKING:
@@ -35,86 +42,52 @@ def _is_fresh(block: BlockData, allowable_delay: int) -> bool:
35
42
  return False
36
43
 
37
44
 
38
- def make_stalecheck_middleware(
39
- allowable_delay: int,
40
- skip_stalecheck_for_methods: Collection[str] = SKIP_STALECHECK_FOR_METHODS,
41
- ) -> Middleware:
42
- """
43
- Use to require that a function will run only of the blockchain is recently updated.
44
-
45
- This middleware takes an argument, so unlike other middleware, you must make the
46
- middleware with a method call.
47
-
48
- For example: `make_stalecheck_middleware(60*5)`
49
-
50
- If the latest block in the chain is older than 5 minutes in this example, then the
51
- middleware will raise a StaleBlockchain exception.
52
- """
53
- if allowable_delay <= 0:
54
- raise ValueError(
55
- "You must set a positive allowable_delay in seconds for this middleware"
56
- )
57
-
58
- def stalecheck_middleware(
59
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "Web3"
60
- ) -> Callable[[RPCEndpoint, Any], RPCResponse]:
61
- cache: Dict[str, Optional[BlockData]] = {"latest": None}
62
-
63
- def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
64
- if method not in skip_stalecheck_for_methods:
65
- if not _is_fresh(cache["latest"], allowable_delay):
66
- latest = w3.eth.get_block("latest")
67
- if _is_fresh(latest, allowable_delay):
68
- cache["latest"] = latest
69
- else:
70
- raise StaleBlockchain(latest, allowable_delay)
71
-
72
- return make_request(method, params)
73
-
45
+ class StalecheckMiddlewareBuilder(Web3MiddlewareBuilder):
46
+ allowable_delay: int
47
+ skip_stalecheck_for_methods: Collection[str]
48
+ cache: Dict[str, Optional[BlockData]]
49
+
50
+ @staticmethod
51
+ @curry
52
+ def build(
53
+ allowable_delay: int,
54
+ w3: Union["Web3", "AsyncWeb3"],
55
+ skip_stalecheck_for_methods: Collection[str] = SKIP_STALECHECK_FOR_METHODS,
56
+ ) -> Web3Middleware:
57
+ if allowable_delay <= 0:
58
+ raise Web3ValueError(
59
+ "You must set a positive allowable_delay in seconds for this middleware"
60
+ )
61
+ middleware = StalecheckMiddlewareBuilder(w3)
62
+ middleware.allowable_delay = allowable_delay
63
+ middleware.skip_stalecheck_for_methods = skip_stalecheck_for_methods
64
+ middleware.cache = {"latest": None}
74
65
  return middleware
75
66
 
76
- return stalecheck_middleware
77
-
78
-
79
- # -- async -- #
80
-
67
+ def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
68
+ if method not in self.skip_stalecheck_for_methods:
69
+ if not _is_fresh(self.cache["latest"], self.allowable_delay):
70
+ w3 = cast("Web3", self._w3)
71
+ latest = w3.eth.get_block("latest")
81
72
 
82
- async def async_make_stalecheck_middleware(
83
- allowable_delay: int,
84
- skip_stalecheck_for_methods: Collection[str] = SKIP_STALECHECK_FOR_METHODS,
85
- ) -> AsyncMiddleware:
86
- """
87
- Use to require that a function will run only of the blockchain is recently updated.
73
+ if _is_fresh(latest, self.allowable_delay):
74
+ self.cache["latest"] = latest
75
+ else:
76
+ raise StaleBlockchain(latest, self.allowable_delay)
88
77
 
89
- This middleware takes an argument, so unlike other middleware, you must make the
90
- middleware with a method call.
78
+ return method, params
91
79
 
92
- For example: `async_make_stalecheck_middleware(60*5)`
80
+ # -- async -- #
93
81
 
94
- If the latest block in the chain is older than 5 minutes in this example, then the
95
- middleware will raise a StaleBlockchain exception.
96
- """
97
- if allowable_delay <= 0:
98
- raise ValueError(
99
- "You must set a positive allowable_delay in seconds for this middleware"
100
- )
82
+ async def async_request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
83
+ if method not in self.skip_stalecheck_for_methods:
84
+ if not _is_fresh(self.cache["latest"], self.allowable_delay):
85
+ w3 = cast("AsyncWeb3", self._w3)
86
+ latest = await w3.eth.get_block("latest")
101
87
 
102
- async def stalecheck_middleware(
103
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "AsyncWeb3"
104
- ) -> AsyncMiddlewareCoroutine:
105
- cache: Dict[str, Optional[BlockData]] = {"latest": None}
106
-
107
- async def middleware(method: RPCEndpoint, params: Any) -> RPCResponse:
108
- if method not in skip_stalecheck_for_methods:
109
- if not _is_fresh(cache["latest"], allowable_delay):
110
- latest = await w3.eth.get_block("latest")
111
- if _is_fresh(latest, allowable_delay):
112
- cache["latest"] = latest
113
- else:
114
- raise StaleBlockchain(latest, allowable_delay)
115
-
116
- return await make_request(method, params)
117
-
118
- return middleware
88
+ if _is_fresh(latest, self.allowable_delay):
89
+ self.cache["latest"] = latest
90
+ else:
91
+ raise StaleBlockchain(latest, self.allowable_delay)
119
92
 
120
- return stalecheck_middleware
93
+ return method, params
@@ -33,11 +33,9 @@ from web3.exceptions import (
33
33
  Web3ValidationError,
34
34
  )
35
35
  from web3.middleware.formatting import (
36
- async_construct_web3_formatting_middleware,
37
- construct_web3_formatting_middleware,
36
+ FormattingMiddlewareBuilder,
38
37
  )
39
38
  from web3.types import (
40
- AsyncMiddlewareCoroutine,
41
39
  Formatters,
42
40
  FormattersDict,
43
41
  RPCEndpoint,
@@ -147,9 +145,6 @@ def build_method_validators(w3: "Web3", method: RPCEndpoint) -> FormattersDict:
147
145
  return _build_formatters_dict(request_formatters)
148
146
 
149
147
 
150
- validation_middleware = construct_web3_formatting_middleware(build_method_validators)
151
-
152
-
153
148
  # -- async --- #
154
149
 
155
150
 
@@ -165,10 +160,7 @@ async def async_build_method_validators(
165
160
  return _build_formatters_dict(request_formatters)
166
161
 
167
162
 
168
- async def async_validation_middleware(
169
- make_request: Callable[[RPCEndpoint, Any], Any], w3: "AsyncWeb3"
170
- ) -> AsyncMiddlewareCoroutine:
171
- middleware = await async_construct_web3_formatting_middleware(
172
- async_build_method_validators
173
- )
174
- return await middleware(make_request, w3)
163
+ ValidationMiddleware = FormattingMiddlewareBuilder.build(
164
+ sync_formatters_builder=build_method_validators,
165
+ async_formatters_builder=async_build_method_validators,
166
+ )
web3/module.py CHANGED
@@ -5,6 +5,8 @@ from typing import (
5
5
  Coroutine,
6
6
  Dict,
7
7
  Optional,
8
+ Sequence,
9
+ Tuple,
8
10
  TypeVar,
9
11
  Union,
10
12
  cast,
@@ -55,9 +57,43 @@ def apply_result_formatters(
55
57
  TReturn = TypeVar("TReturn")
56
58
 
57
59
 
60
+ @curry
61
+ def retrieve_request_information_for_batching(
62
+ w3: Union["AsyncWeb3", "Web3"],
63
+ module: "Module",
64
+ method: Method[Callable[..., Any]],
65
+ ) -> Union[
66
+ Callable[..., Tuple[Tuple[RPCEndpoint, Any], Sequence[Any]]],
67
+ Callable[..., Coroutine[Any, Any, Tuple[Tuple[RPCEndpoint, Any], Sequence[Any]]]],
68
+ ]:
69
+ async def async_inner(
70
+ *args: Any, **kwargs: Any
71
+ ) -> Tuple[Tuple[RPCEndpoint, Any], Sequence[Any]]:
72
+ (method_str, params), response_formatters = method.process_params(
73
+ module, *args, **kwargs
74
+ )
75
+ if isinstance(w3.provider, PersistentConnectionProvider):
76
+ w3.provider._request_processor.cache_request_information(
77
+ cast(RPCEndpoint, method_str), params, response_formatters
78
+ )
79
+ return (cast(RPCEndpoint, method_str), params), response_formatters
80
+
81
+ def inner(
82
+ *args: Any, **kwargs: Any
83
+ ) -> Tuple[Tuple[RPCEndpoint, Any], Sequence[Any]]:
84
+ (method_str, params), response_formatters = method.process_params(
85
+ module, *args, **kwargs
86
+ )
87
+ return (cast(RPCEndpoint, method_str), params), response_formatters
88
+
89
+ return async_inner if module.is_async else inner
90
+
91
+
58
92
  @curry
59
93
  def retrieve_blocking_method_call_fn(
60
- w3: "Web3", module: "Module", method: Method[Callable[..., TReturn]]
94
+ w3: "Web3",
95
+ module: "Module",
96
+ method: Method[Callable[..., TReturn]],
61
97
  ) -> Callable[..., Union[TReturn, LogFilter]]:
62
98
  def caller(*args: Any, **kwargs: Any) -> Union[TReturn, LogFilter]:
63
99
  try:
@@ -82,7 +118,9 @@ def retrieve_blocking_method_call_fn(
82
118
 
83
119
  @curry
84
120
  def retrieve_async_method_call_fn(
85
- async_w3: "AsyncWeb3", module: "Module", method: Method[Callable[..., Any]]
121
+ async_w3: "AsyncWeb3",
122
+ module: "Module",
123
+ method: Method[Callable[..., Any]],
86
124
  ) -> Callable[..., Coroutine[Any, Any, Optional[Union[RPCResponse, AsyncLogFilter]]]]:
87
125
  async def caller(*args: Any, **kwargs: Any) -> Union[RPCResponse, AsyncLogFilter]:
88
126
  try:
@@ -93,17 +131,20 @@ def retrieve_async_method_call_fn(
93
131
  return AsyncLogFilter(eth_module=module, filter_id=err.filter_id)
94
132
 
95
133
  if isinstance(async_w3.provider, PersistentConnectionProvider):
96
- # TODO: The typing does not seem to be correct for response_formatters.
97
- # For now, keep the expected typing but ignore it here.
98
134
  provider = async_w3.provider
99
135
  cache_key = provider._request_processor.cache_request_information(
100
- method_str, params, response_formatters # type: ignore
136
+ cast(RPCEndpoint, method_str), params, response_formatters
101
137
  )
138
+
102
139
  try:
103
140
  method_str = cast(RPCEndpoint, method_str)
104
- return await async_w3.manager.ws_send(method_str, params)
141
+ return await async_w3.manager.socket_request(method_str, params)
105
142
  except Exception as e:
106
- if cache_key in provider._request_processor._request_information_cache:
143
+ if (
144
+ cache_key is not None
145
+ and cache_key
146
+ in provider._request_processor._request_information_cache
147
+ ):
107
148
  provider._request_processor.pop_cached_request_information(
108
149
  cache_key
109
150
  )
@@ -125,7 +166,7 @@ def retrieve_async_method_call_fn(
125
166
 
126
167
  # Module should no longer have access to the full web3 api.
127
168
  # Only the calling functions need access to the request methods.
128
- # Any "re-entrant" shenanigans can go in the middlewares, which do
169
+ # Any "re-entrant" shenanigans can go in the middleware, which do
129
170
  # have web3 access.
130
171
  class Module:
131
172
  is_async = False
@@ -135,6 +176,9 @@ class Module:
135
176
  self.retrieve_caller_fn = retrieve_async_method_call_fn(w3, self)
136
177
  else:
137
178
  self.retrieve_caller_fn = retrieve_blocking_method_call_fn(w3, self)
179
+ self.retrieve_request_information = retrieve_request_information_for_batching(
180
+ w3, self
181
+ )
138
182
  self.w3 = w3
139
183
 
140
184
  @property
@@ -148,8 +192,8 @@ class Module:
148
192
  ) -> None:
149
193
  for method_name, method_class in methods.items():
150
194
  klass = (
151
- method_class.__get__(obj=self)()
195
+ method_class.__get__(module=self)()
152
196
  if method_class.is_property
153
- else method_class.__get__(obj=self)
197
+ else method_class.__get__(module=self)
154
198
  )
155
199
  setattr(self, method_name, klass)
@@ -1,7 +1,7 @@
1
1
  from .async_base import (
2
2
  AsyncBaseProvider,
3
3
  )
4
- from .async_rpc import (
4
+ from .rpc import (
5
5
  AsyncHTTPProvider,
6
6
  )
7
7
  from .base import (
@@ -18,12 +18,14 @@ from .ipc import (
18
18
  from .rpc import (
19
19
  HTTPProvider,
20
20
  )
21
- from .websocket import (
22
- WebsocketProvider,
23
- WebsocketProviderV2,
21
+ from .legacy_websocket import (
22
+ LegacyWebSocketProvider,
24
23
  )
25
24
  from .persistent import (
25
+ AsyncIPCProvider,
26
+ PersistentConnection,
26
27
  PersistentConnectionProvider,
28
+ WebSocketProvider,
27
29
  )
28
30
  from .auto import (
29
31
  AutoProvider,
@@ -33,13 +35,15 @@ __all__ = [
33
35
  "AsyncBaseProvider",
34
36
  "AsyncEthereumTesterProvider",
35
37
  "AsyncHTTPProvider",
38
+ "AsyncIPCProvider",
36
39
  "AutoProvider",
37
40
  "BaseProvider",
38
41
  "EthereumTesterProvider",
39
42
  "HTTPProvider",
40
43
  "IPCProvider",
41
44
  "JSONBaseProvider",
45
+ "LegacyWebSocketProvider",
46
+ "PersistentConnection",
42
47
  "PersistentConnectionProvider",
43
- "WebsocketProvider",
44
- "WebsocketProviderV2",
48
+ "WebSocketProvider",
45
49
  ]