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.
- ens/__init__.py +13 -2
- ens/_normalization.py +2 -17
- ens/async_ens.py +33 -21
- ens/base_ens.py +3 -1
- ens/ens.py +16 -11
- ens/exceptions.py +16 -29
- ens/specs/nf.json +1 -1
- ens/specs/normalization_spec.json +1 -1
- ens/utils.py +52 -63
- web3/__init__.py +20 -24
- web3/_utils/abi.py +115 -271
- web3/_utils/async_transactions.py +7 -4
- web3/_utils/batching.py +217 -0
- web3/_utils/blocks.py +6 -2
- web3/_utils/caching.py +128 -5
- web3/_utils/compat/__init__.py +2 -3
- web3/_utils/contract_sources/compile_contracts.py +1 -1
- web3/_utils/contract_sources/contract_data/arrays_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/bytes_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/constructor_contracts.py +7 -7
- web3/_utils/contract_sources/contract_data/contract_caller_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/emitter_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/event_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/extended_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/fallback_function_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/function_name_tester_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/math_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_lookup.py +3 -3
- web3/_utils/contract_sources/contract_data/offchain_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/panic_errors_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/payable_tester.py +3 -3
- web3/_utils/contract_sources/contract_data/receive_function_contracts.py +5 -5
- web3/_utils/contract_sources/contract_data/reflector_contracts.py +3 -3
- web3/_utils/contract_sources/contract_data/revert_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/simple_resolver.py +3 -3
- web3/_utils/contract_sources/contract_data/storage_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/string_contract.py +3 -3
- web3/_utils/contract_sources/contract_data/tuple_contracts.py +5 -5
- web3/_utils/contracts.py +130 -236
- web3/_utils/datatypes.py +5 -1
- web3/_utils/decorators.py +13 -23
- web3/_utils/empty.py +1 -1
- web3/_utils/encoding.py +16 -12
- web3/_utils/ens.py +2 -1
- web3/_utils/error_formatters_utils.py +5 -3
- web3/_utils/events.py +66 -69
- web3/_utils/fee_utils.py +1 -3
- web3/_utils/filters.py +24 -22
- web3/_utils/formatters.py +2 -2
- web3/_utils/http.py +5 -3
- web3/_utils/http_session_manager.py +303 -0
- web3/_utils/math.py +14 -15
- web3/_utils/method_formatters.py +34 -36
- web3/_utils/module.py +2 -1
- web3/_utils/module_testing/__init__.py +0 -3
- web3/_utils/module_testing/eth_module.py +695 -643
- web3/_utils/module_testing/module_testing_utils.py +61 -34
- web3/_utils/module_testing/persistent_connection_provider.py +56 -25
- web3/_utils/module_testing/utils.py +258 -0
- web3/_utils/module_testing/web3_module.py +438 -17
- web3/_utils/normalizers.py +13 -11
- web3/_utils/rpc_abi.py +5 -32
- web3/_utils/threads.py +8 -7
- web3/_utils/transactions.py +14 -12
- web3/_utils/type_conversion.py +5 -1
- web3/_utils/validation.py +17 -17
- web3/auto/gethdev.py +7 -2
- web3/beacon/__init__.py +6 -1
- web3/beacon/async_beacon.py +9 -5
- web3/beacon/{main.py → beacon.py} +7 -5
- web3/contract/__init__.py +7 -0
- web3/contract/async_contract.py +47 -46
- web3/contract/base_contract.py +183 -158
- web3/contract/contract.py +49 -43
- web3/contract/utils.py +203 -59
- web3/datastructures.py +79 -31
- web3/eth/__init__.py +7 -0
- web3/eth/async_eth.py +39 -51
- web3/eth/base_eth.py +17 -10
- web3/eth/eth.py +30 -68
- web3/exceptions.py +108 -82
- web3/gas_strategies/time_based.py +8 -6
- web3/geth.py +1 -254
- web3/main.py +75 -122
- web3/manager.py +316 -146
- web3/method.py +38 -31
- web3/middleware/__init__.py +67 -89
- web3/middleware/attrdict.py +36 -49
- web3/middleware/base.py +174 -0
- web3/middleware/buffered_gas_estimate.py +20 -21
- web3/middleware/filter.py +157 -117
- web3/middleware/formatting.py +124 -108
- web3/middleware/gas_price_strategy.py +20 -32
- web3/middleware/names.py +29 -26
- web3/middleware/proof_of_authority.py +68 -0
- web3/middleware/pythonic.py +2 -2
- web3/middleware/signing.py +74 -89
- web3/middleware/stalecheck.py +52 -79
- web3/middleware/validation.py +5 -13
- web3/module.py +54 -10
- web3/providers/__init__.py +10 -6
- web3/providers/async_base.py +117 -39
- web3/providers/auto.py +3 -3
- web3/providers/base.py +89 -33
- web3/providers/eth_tester/__init__.py +5 -0
- web3/providers/eth_tester/defaults.py +1 -64
- web3/providers/eth_tester/main.py +99 -31
- web3/providers/eth_tester/middleware.py +45 -73
- web3/providers/ipc.py +42 -46
- web3/providers/{websocket/websocket.py → legacy_websocket.py} +32 -7
- web3/providers/persistent/__init__.py +22 -0
- web3/providers/persistent/async_ipc.py +153 -0
- web3/providers/{persistent.py → persistent/persistent.py} +106 -25
- web3/providers/persistent/persistent_connection.py +84 -0
- web3/providers/{websocket → persistent}/request_processor.py +94 -32
- web3/providers/persistent/utils.py +43 -0
- web3/providers/{websocket/websocket_v2.py → persistent/websocket.py} +29 -28
- web3/providers/rpc/__init__.py +11 -0
- web3/providers/rpc/async_rpc.py +171 -0
- web3/providers/rpc/rpc.py +179 -0
- web3/providers/rpc/utils.py +92 -0
- web3/testing.py +4 -4
- web3/tools/benchmark/main.py +22 -22
- web3/tools/benchmark/node.py +2 -8
- web3/tools/benchmark/reporting.py +2 -2
- web3/tools/benchmark/utils.py +1 -1
- web3/tracing.py +9 -5
- web3/types.py +30 -107
- web3/utils/__init__.py +58 -5
- web3/utils/abi.py +575 -10
- web3/utils/async_exception_handling.py +19 -7
- web3/utils/caching.py +32 -13
- web3/utils/exception_handling.py +7 -5
- {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/LICENSE +1 -1
- web3-7.0.0.dist-info/METADATA +112 -0
- web3-7.0.0.dist-info/RECORD +167 -0
- {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/WHEEL +1 -1
- {web3-6.20.2.dist-info → web3-7.0.0.dist-info}/top_level.txt +0 -1
- ethpm/__init__.py +0 -20
- ethpm/_utils/__init__.py +0 -0
- ethpm/_utils/backend.py +0 -93
- ethpm/_utils/cache.py +0 -44
- ethpm/_utils/chains.py +0 -119
- ethpm/_utils/contract.py +0 -35
- ethpm/_utils/deployments.py +0 -145
- ethpm/_utils/ipfs.py +0 -116
- ethpm/_utils/protobuf/__init__.py +0 -0
- ethpm/_utils/protobuf/ipfs_file_pb2.py +0 -33
- ethpm/_utils/registry.py +0 -29
- ethpm/assets/__init__.py +0 -0
- ethpm/assets/ens/v3.json +0 -1
- ethpm/assets/escrow/with_bytecode_v3.json +0 -1
- ethpm/assets/ipfs_file.proto +0 -32
- ethpm/assets/owned/output_v3.json +0 -1
- ethpm/assets/owned/with_contract_type_v3.json +0 -1
- ethpm/assets/registry/contracts/Authority.sol +0 -156
- ethpm/assets/registry/contracts/IndexedOrderedSetLib.sol +0 -106
- ethpm/assets/registry/contracts/PackageDB.sol +0 -225
- ethpm/assets/registry/contracts/PackageRegistry.sol +0 -361
- ethpm/assets/registry/contracts/PackageRegistryInterface.sol +0 -97
- ethpm/assets/registry/contracts/ReleaseDB.sol +0 -309
- ethpm/assets/registry/contracts/ReleaseValidator.sol +0 -152
- ethpm/assets/registry/solc_input.json +0 -1
- ethpm/assets/registry/solc_output.json +0 -1
- ethpm/assets/registry/v3.json +0 -1
- ethpm/assets/safe-math-lib/v3-strict-no-deployments.json +0 -1
- ethpm/assets/simple-registry/contracts/Ownable.sol +0 -63
- ethpm/assets/simple-registry/contracts/PackageRegistry.sol +0 -373
- ethpm/assets/simple-registry/contracts/PackageRegistryInterface.sol +0 -96
- ethpm/assets/simple-registry/solc_input.json +0 -33
- ethpm/assets/simple-registry/solc_output.json +0 -1
- ethpm/assets/simple-registry/v3.json +0 -1
- ethpm/assets/standard-token/output_v3.json +0 -1
- ethpm/assets/standard-token/with_bytecode_v3.json +0 -1
- ethpm/assets/vyper_registry/0.1.0.json +0 -1
- ethpm/assets/vyper_registry/registry.vy +0 -216
- ethpm/assets/vyper_registry/registry_with_delete.vy +0 -244
- ethpm/backends/__init__.py +0 -0
- ethpm/backends/base.py +0 -43
- ethpm/backends/http.py +0 -108
- ethpm/backends/ipfs.py +0 -219
- ethpm/backends/registry.py +0 -154
- ethpm/constants.py +0 -17
- ethpm/contract.py +0 -187
- ethpm/dependencies.py +0 -58
- ethpm/deployments.py +0 -80
- ethpm/ethpm-spec/examples/escrow/1.0.0-pretty.json +0 -146
- ethpm/ethpm-spec/examples/escrow/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/escrow/contracts/Escrow.sol +0 -32
- ethpm/ethpm-spec/examples/escrow/contracts/SafeSendLib.sol +0 -20
- ethpm/ethpm-spec/examples/escrow/v3-pretty.json +0 -171
- ethpm/ethpm-spec/examples/escrow/v3.json +0 -1
- ethpm/ethpm-spec/examples/owned/1.0.0-pretty.json +0 -21
- ethpm/ethpm-spec/examples/owned/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/owned/contracts/Owned.sol +0 -12
- ethpm/ethpm-spec/examples/owned/v3-pretty.json +0 -27
- ethpm/ethpm-spec/examples/owned/v3.json +0 -1
- ethpm/ethpm-spec/examples/piper-coin/1.0.0-pretty.json +0 -31
- ethpm/ethpm-spec/examples/piper-coin/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/piper-coin/v3-pretty.json +0 -21
- ethpm/ethpm-spec/examples/piper-coin/v3.json +0 -1
- ethpm/ethpm-spec/examples/safe-math-lib/1.0.0-pretty.json +0 -85
- ethpm/ethpm-spec/examples/safe-math-lib/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/safe-math-lib/contracts/SafeMathLib.sol +0 -24
- ethpm/ethpm-spec/examples/safe-math-lib/v3-pretty.json +0 -117
- ethpm/ethpm-spec/examples/safe-math-lib/v3.json +0 -1
- ethpm/ethpm-spec/examples/standard-token/1.0.0-pretty.json +0 -55
- ethpm/ethpm-spec/examples/standard-token/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/standard-token/contracts/AbstractToken.sol +0 -20
- ethpm/ethpm-spec/examples/standard-token/contracts/StandardToken.sol +0 -84
- ethpm/ethpm-spec/examples/standard-token/v3-pretty.json +0 -460
- ethpm/ethpm-spec/examples/standard-token/v3.json +0 -1
- ethpm/ethpm-spec/examples/transferable/1.0.0-pretty.json +0 -21
- ethpm/ethpm-spec/examples/transferable/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/transferable/contracts/Transferable.sol +0 -14
- ethpm/ethpm-spec/examples/transferable/v3-pretty.json +0 -27
- ethpm/ethpm-spec/examples/transferable/v3.json +0 -1
- ethpm/ethpm-spec/examples/wallet/1.0.0-pretty.json +0 -120
- ethpm/ethpm-spec/examples/wallet/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/wallet/contracts/Wallet.sol +0 -41
- ethpm/ethpm-spec/examples/wallet/v3-pretty.json +0 -181
- ethpm/ethpm-spec/examples/wallet/v3.json +0 -1
- ethpm/ethpm-spec/examples/wallet-with-send/1.0.0-pretty.json +0 -135
- ethpm/ethpm-spec/examples/wallet-with-send/1.0.0.json +0 -1
- ethpm/ethpm-spec/examples/wallet-with-send/contracts/WalletWithSend.sol +0 -18
- ethpm/ethpm-spec/examples/wallet-with-send/v3-pretty.json +0 -207
- ethpm/ethpm-spec/examples/wallet-with-send/v3.json +0 -1
- ethpm/ethpm-spec/spec/package.spec.json +0 -379
- ethpm/ethpm-spec/spec/v3.spec.json +0 -483
- ethpm/exceptions.py +0 -68
- ethpm/package.py +0 -438
- ethpm/tools/__init__.py +0 -4
- ethpm/tools/builder.py +0 -930
- ethpm/tools/checker.py +0 -312
- ethpm/tools/get_manifest.py +0 -19
- ethpm/uri.py +0 -141
- ethpm/validation/__init__.py +0 -0
- ethpm/validation/manifest.py +0 -146
- ethpm/validation/misc.py +0 -39
- ethpm/validation/package.py +0 -80
- ethpm/validation/uri.py +0 -163
- web3/_utils/contract_sources/contract_data/address_reflector.py +0 -29
- web3/_utils/miner.py +0 -88
- web3/_utils/module_testing/go_ethereum_personal_module.py +0 -323
- web3/_utils/request.py +0 -265
- web3/middleware/abi.py +0 -11
- web3/middleware/async_cache.py +0 -99
- web3/middleware/cache.py +0 -374
- web3/middleware/exception_handling.py +0 -49
- web3/middleware/exception_retry_request.py +0 -188
- web3/middleware/fixture.py +0 -190
- web3/middleware/geth_poa.py +0 -81
- web3/middleware/normalize_request_parameters.py +0 -11
- web3/middleware/simulate_unmined_transaction.py +0 -43
- web3/pm.py +0 -602
- web3/providers/async_rpc.py +0 -99
- web3/providers/rpc.py +0 -98
- web3/providers/websocket/__init__.py +0 -11
- web3/providers/websocket/websocket_connection.py +0 -42
- web3/tools/__init__.py +0 -4
- web3/tools/pytest_ethereum/__init__.py +0 -0
- web3/tools/pytest_ethereum/_utils.py +0 -145
- web3/tools/pytest_ethereum/deployer.py +0 -48
- web3/tools/pytest_ethereum/exceptions.py +0 -22
- web3/tools/pytest_ethereum/linker.py +0 -128
- web3/tools/pytest_ethereum/plugins.py +0 -33
- web3-6.20.2.dist-info/METADATA +0 -103
- web3-6.20.2.dist-info/RECORD +0 -283
- web3-6.20.2.dist-info/entry_points.txt +0 -2
- /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
web3/method.py
CHANGED
|
@@ -10,7 +10,6 @@ from typing import (
|
|
|
10
10
|
Sequence,
|
|
11
11
|
Tuple,
|
|
12
12
|
Type,
|
|
13
|
-
TypeVar,
|
|
14
13
|
Union,
|
|
15
14
|
)
|
|
16
15
|
import warnings
|
|
@@ -22,6 +21,9 @@ from eth_utils.toolz import (
|
|
|
22
21
|
pipe,
|
|
23
22
|
)
|
|
24
23
|
|
|
24
|
+
from web3._utils.batching import (
|
|
25
|
+
RPC_METHODS_UNSUPPORTED_DURING_BATCH,
|
|
26
|
+
)
|
|
25
27
|
from web3._utils.method_formatters import (
|
|
26
28
|
get_error_formatters,
|
|
27
29
|
get_null_result_formatters,
|
|
@@ -32,15 +34,22 @@ from web3._utils.rpc_abi import (
|
|
|
32
34
|
RPC,
|
|
33
35
|
)
|
|
34
36
|
from web3.exceptions import (
|
|
37
|
+
MethodNotSupported,
|
|
38
|
+
Web3TypeError,
|
|
35
39
|
Web3ValidationError,
|
|
40
|
+
Web3ValueError,
|
|
36
41
|
)
|
|
37
42
|
from web3.types import (
|
|
38
43
|
RPCEndpoint,
|
|
44
|
+
TFunc,
|
|
39
45
|
TReturn,
|
|
40
46
|
)
|
|
41
47
|
|
|
42
48
|
if TYPE_CHECKING:
|
|
43
|
-
from web3 import
|
|
49
|
+
from web3 import ( # noqa: F401
|
|
50
|
+
PersistentConnectionProvider,
|
|
51
|
+
Web3,
|
|
52
|
+
)
|
|
44
53
|
from web3.module import Module # noqa: F401
|
|
45
54
|
|
|
46
55
|
|
|
@@ -82,11 +91,9 @@ def default_root_munger(_module: "Module", *args: Any) -> List[Any]:
|
|
|
82
91
|
return [*args]
|
|
83
92
|
|
|
84
93
|
|
|
85
|
-
TFunc = TypeVar("TFunc", bound=Callable[..., Any])
|
|
86
|
-
|
|
87
|
-
|
|
88
94
|
class Method(Generic[TFunc]):
|
|
89
|
-
"""
|
|
95
|
+
"""
|
|
96
|
+
Method object for web3 module methods
|
|
90
97
|
|
|
91
98
|
Calls to the Method go through these steps:
|
|
92
99
|
|
|
@@ -146,15 +153,31 @@ class Method(Generic[TFunc]):
|
|
|
146
153
|
self.is_property = is_property
|
|
147
154
|
|
|
148
155
|
def __get__(
|
|
149
|
-
self,
|
|
156
|
+
self,
|
|
157
|
+
module: Optional["Module"] = None,
|
|
158
|
+
_type: Optional[Type["Module"]] = None,
|
|
150
159
|
) -> TFunc:
|
|
151
|
-
|
|
152
|
-
|
|
160
|
+
self._module = module
|
|
161
|
+
if module is None:
|
|
162
|
+
raise Web3TypeError(
|
|
153
163
|
"Direct calls to methods are not supported. "
|
|
154
|
-
"Methods must be called from
|
|
164
|
+
"Methods must be called from a module instance, "
|
|
155
165
|
"usually attached to a web3 instance."
|
|
156
166
|
)
|
|
157
|
-
|
|
167
|
+
|
|
168
|
+
provider = module.w3.provider
|
|
169
|
+
if hasattr(provider, "_is_batching") and provider._is_batching:
|
|
170
|
+
if self.json_rpc_method in RPC_METHODS_UNSUPPORTED_DURING_BATCH:
|
|
171
|
+
raise MethodNotSupported(
|
|
172
|
+
f"Method `{self.json_rpc_method}` is not supported within a batch "
|
|
173
|
+
"request."
|
|
174
|
+
)
|
|
175
|
+
return module.retrieve_request_information(self)
|
|
176
|
+
else:
|
|
177
|
+
return module.retrieve_caller_fn(self)
|
|
178
|
+
|
|
179
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
180
|
+
return self.__get__(self._module)(*args, **kwargs)
|
|
158
181
|
|
|
159
182
|
@property
|
|
160
183
|
def method_selector_fn(
|
|
@@ -165,7 +188,7 @@ class Method(Generic[TFunc]):
|
|
|
165
188
|
return self.json_rpc_method
|
|
166
189
|
elif isinstance(self.json_rpc_method, (str,)):
|
|
167
190
|
return lambda *_: self.json_rpc_method
|
|
168
|
-
raise
|
|
191
|
+
raise Web3ValueError(
|
|
169
192
|
"``json_rpc_method`` config invalid. May be a string or function"
|
|
170
193
|
)
|
|
171
194
|
|
|
@@ -218,34 +241,18 @@ class Method(Generic[TFunc]):
|
|
|
218
241
|
|
|
219
242
|
class DeprecatedMethod:
|
|
220
243
|
def __init__(
|
|
221
|
-
self,
|
|
222
|
-
method: Method[Callable[..., Any]],
|
|
223
|
-
old_name: Optional[str] = None,
|
|
224
|
-
new_name: Optional[str] = None,
|
|
225
|
-
msg: Optional[str] = None,
|
|
244
|
+
self, method: Method[Callable[..., Any]], old_name: str, new_name: str
|
|
226
245
|
) -> None:
|
|
227
246
|
self.method = method
|
|
228
247
|
self.old_name = old_name
|
|
229
248
|
self.new_name = new_name
|
|
230
|
-
self.msg = msg
|
|
231
249
|
|
|
232
250
|
def __get__(
|
|
233
251
|
self, obj: Optional["Module"] = None, obj_type: Optional[Type["Module"]] = None
|
|
234
252
|
) -> Any:
|
|
235
|
-
if self.old_name is not None and self.new_name is not None:
|
|
236
|
-
if self.msg is not None:
|
|
237
|
-
raise ValueError(
|
|
238
|
-
"Cannot specify `old_name` and `new_name` along with `msg`"
|
|
239
|
-
)
|
|
240
|
-
|
|
241
|
-
message = f"{self.old_name} is deprecated in favor of {self.new_name}"
|
|
242
|
-
elif self.msg is not None:
|
|
243
|
-
message = self.msg
|
|
244
|
-
else:
|
|
245
|
-
raise ValueError("Must provide either `old_name` and `new_name` or `msg`")
|
|
246
|
-
|
|
247
253
|
warnings.warn(
|
|
248
|
-
|
|
254
|
+
f"{self.old_name} is deprecated in favor of {self.new_name}",
|
|
249
255
|
category=DeprecationWarning,
|
|
256
|
+
stacklevel=2,
|
|
250
257
|
)
|
|
251
258
|
return self.method.__get__(obj, obj_type)
|
web3/middleware/__init__.py
CHANGED
|
@@ -1,133 +1,111 @@
|
|
|
1
|
-
import functools
|
|
2
1
|
from typing import (
|
|
3
|
-
Coroutine,
|
|
4
2
|
TYPE_CHECKING,
|
|
5
3
|
Any,
|
|
6
4
|
Callable,
|
|
5
|
+
Coroutine,
|
|
7
6
|
Sequence,
|
|
8
7
|
)
|
|
9
8
|
|
|
10
|
-
from web3.types import (
|
|
11
|
-
AsyncMiddleware,
|
|
12
|
-
Middleware,
|
|
13
|
-
RPCEndpoint,
|
|
14
|
-
RPCResponse,
|
|
15
|
-
)
|
|
16
|
-
|
|
17
|
-
from .abi import (
|
|
18
|
-
abi_middleware,
|
|
19
|
-
)
|
|
20
|
-
from .async_cache import (
|
|
21
|
-
_async_simple_cache_middleware as async_simple_cache_middleware,
|
|
22
|
-
async_construct_simple_cache_middleware,
|
|
23
|
-
)
|
|
24
9
|
from .attrdict import (
|
|
25
|
-
|
|
26
|
-
attrdict_middleware,
|
|
27
|
-
)
|
|
28
|
-
from .buffered_gas_estimate import (
|
|
29
|
-
async_buffered_gas_estimate_middleware,
|
|
30
|
-
buffered_gas_estimate_middleware,
|
|
10
|
+
AttributeDictMiddleware,
|
|
31
11
|
)
|
|
32
|
-
from .
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
_time_based_cache_middleware as time_based_cache_middleware,
|
|
36
|
-
construct_latest_block_based_cache_middleware,
|
|
37
|
-
construct_simple_cache_middleware,
|
|
38
|
-
construct_time_based_cache_middleware,
|
|
39
|
-
)
|
|
40
|
-
from .exception_handling import (
|
|
41
|
-
construct_exception_handler_middleware,
|
|
12
|
+
from .base import (
|
|
13
|
+
Middleware,
|
|
14
|
+
Web3Middleware,
|
|
42
15
|
)
|
|
43
|
-
from .
|
|
44
|
-
|
|
45
|
-
http_retry_request_middleware,
|
|
16
|
+
from .buffered_gas_estimate import (
|
|
17
|
+
BufferedGasEstimateMiddleware,
|
|
46
18
|
)
|
|
47
19
|
from .filter import (
|
|
48
|
-
|
|
49
|
-
local_filter_middleware,
|
|
50
|
-
)
|
|
51
|
-
from .fixture import (
|
|
52
|
-
async_construct_error_generator_middleware,
|
|
53
|
-
async_construct_result_generator_middleware,
|
|
54
|
-
construct_error_generator_middleware,
|
|
55
|
-
construct_fixture_middleware,
|
|
56
|
-
construct_result_generator_middleware,
|
|
20
|
+
LocalFilterMiddleware,
|
|
57
21
|
)
|
|
58
22
|
from .formatting import (
|
|
59
|
-
|
|
23
|
+
FormattingMiddlewareBuilder,
|
|
60
24
|
)
|
|
61
25
|
from .gas_price_strategy import (
|
|
62
|
-
|
|
63
|
-
gas_price_strategy_middleware,
|
|
64
|
-
)
|
|
65
|
-
from .geth_poa import (
|
|
66
|
-
async_geth_poa_middleware,
|
|
67
|
-
geth_poa_middleware,
|
|
26
|
+
GasPriceStrategyMiddleware,
|
|
68
27
|
)
|
|
69
28
|
from .names import (
|
|
70
|
-
|
|
71
|
-
name_to_address_middleware,
|
|
29
|
+
ENSNameToAddressMiddleware,
|
|
72
30
|
)
|
|
73
|
-
from .
|
|
74
|
-
|
|
31
|
+
from .proof_of_authority import (
|
|
32
|
+
ExtraDataToPOAMiddleware,
|
|
75
33
|
)
|
|
76
34
|
from .pythonic import (
|
|
77
|
-
|
|
35
|
+
PythonicMiddleware,
|
|
78
36
|
)
|
|
79
37
|
from .signing import (
|
|
80
|
-
|
|
38
|
+
SignAndSendRawMiddlewareBuilder,
|
|
81
39
|
)
|
|
82
40
|
from .stalecheck import (
|
|
83
|
-
|
|
84
|
-
make_stalecheck_middleware,
|
|
41
|
+
StalecheckMiddlewareBuilder,
|
|
85
42
|
)
|
|
86
43
|
from .validation import (
|
|
87
|
-
|
|
88
|
-
validation_middleware,
|
|
44
|
+
ValidationMiddleware,
|
|
89
45
|
)
|
|
46
|
+
from ..types import (
|
|
47
|
+
AsyncMakeRequestFn,
|
|
48
|
+
MakeRequestFn,
|
|
49
|
+
)
|
|
50
|
+
|
|
90
51
|
|
|
91
52
|
if TYPE_CHECKING:
|
|
92
|
-
from web3 import
|
|
53
|
+
from web3 import (
|
|
54
|
+
AsyncWeb3,
|
|
55
|
+
Web3,
|
|
56
|
+
)
|
|
57
|
+
from web3.types import (
|
|
58
|
+
RPCResponse,
|
|
59
|
+
)
|
|
93
60
|
|
|
94
61
|
|
|
95
|
-
def
|
|
96
|
-
|
|
62
|
+
def combine_middleware(
|
|
63
|
+
middleware: Sequence[Middleware],
|
|
97
64
|
w3: "Web3",
|
|
98
|
-
provider_request_fn:
|
|
99
|
-
) -> Callable[..., RPCResponse]:
|
|
65
|
+
provider_request_fn: MakeRequestFn,
|
|
66
|
+
) -> Callable[..., "RPCResponse"]:
|
|
100
67
|
"""
|
|
101
|
-
Returns a callable function which
|
|
102
|
-
|
|
68
|
+
Returns a callable function which takes method and params as positional arguments
|
|
69
|
+
and passes these args through the request processors, makes the request, and passes
|
|
70
|
+
the response through the response processors.
|
|
103
71
|
"""
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
72
|
+
accumulator_fn = provider_request_fn
|
|
73
|
+
for mw in reversed(middleware):
|
|
74
|
+
# initialize the middleware and wrap the accumulator function down the stack
|
|
75
|
+
accumulator_fn = mw(w3).wrap_make_request(accumulator_fn)
|
|
76
|
+
return accumulator_fn
|
|
109
77
|
|
|
110
78
|
|
|
111
|
-
async def
|
|
112
|
-
|
|
79
|
+
async def async_combine_middleware(
|
|
80
|
+
middleware: Sequence[Middleware],
|
|
113
81
|
async_w3: "AsyncWeb3",
|
|
114
|
-
provider_request_fn:
|
|
115
|
-
) -> Callable[..., Coroutine[Any, Any, RPCResponse]]:
|
|
82
|
+
provider_request_fn: AsyncMakeRequestFn,
|
|
83
|
+
) -> Callable[..., Coroutine[Any, Any, "RPCResponse"]]:
|
|
116
84
|
"""
|
|
117
|
-
Returns a callable function which
|
|
118
|
-
|
|
85
|
+
Returns a callable function which takes method and params as positional arguments
|
|
86
|
+
and passes these args through the request processors, makes the request, and passes
|
|
87
|
+
the response through the response processors.
|
|
119
88
|
"""
|
|
120
89
|
accumulator_fn = provider_request_fn
|
|
121
|
-
for
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
)
|
|
90
|
+
for mw in reversed(middleware):
|
|
91
|
+
# initialize the middleware and wrap the accumulator function down the stack
|
|
92
|
+
initialized = mw(async_w3)
|
|
93
|
+
accumulator_fn = await initialized.async_wrap_make_request(accumulator_fn)
|
|
125
94
|
return accumulator_fn
|
|
126
95
|
|
|
127
96
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
97
|
+
__all__ = [
|
|
98
|
+
"AttributeDictMiddleware",
|
|
99
|
+
"Middleware",
|
|
100
|
+
"Web3Middleware",
|
|
101
|
+
"BufferedGasEstimateMiddleware",
|
|
102
|
+
"LocalFilterMiddleware",
|
|
103
|
+
"FormattingMiddlewareBuilder",
|
|
104
|
+
"GasPriceStrategyMiddleware",
|
|
105
|
+
"ENSNameToAddressMiddleware",
|
|
106
|
+
"ExtraDataToPOAMiddleware",
|
|
107
|
+
"PythonicMiddleware",
|
|
108
|
+
"SignAndSendRawMiddlewareBuilder",
|
|
109
|
+
"StalecheckMiddlewareBuilder",
|
|
110
|
+
"ValidationMiddleware",
|
|
111
|
+
]
|
web3/middleware/attrdict.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
from abc import (
|
|
2
|
+
ABC,
|
|
3
|
+
)
|
|
1
4
|
from typing import (
|
|
2
5
|
TYPE_CHECKING,
|
|
3
6
|
Any,
|
|
4
|
-
Callable,
|
|
5
|
-
Optional,
|
|
6
7
|
cast,
|
|
7
8
|
)
|
|
8
9
|
|
|
@@ -13,10 +14,8 @@ from eth_utils.toolz import (
|
|
|
13
14
|
from web3.datastructures import (
|
|
14
15
|
AttributeDict,
|
|
15
16
|
)
|
|
16
|
-
from web3.
|
|
17
|
-
|
|
18
|
-
RPCEndpoint,
|
|
19
|
-
RPCResponse,
|
|
17
|
+
from web3.middleware.base import (
|
|
18
|
+
Web3Middleware,
|
|
20
19
|
)
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
@@ -27,11 +26,31 @@ if TYPE_CHECKING:
|
|
|
27
26
|
from web3.providers import ( # noqa: F401
|
|
28
27
|
PersistentConnectionProvider,
|
|
29
28
|
)
|
|
29
|
+
from web3.types import ( # noqa: F401
|
|
30
|
+
RPCEndpoint,
|
|
31
|
+
RPCResponse,
|
|
32
|
+
)
|
|
30
33
|
|
|
31
34
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
def _handle_async_response(response: "RPCResponse") -> "RPCResponse":
|
|
36
|
+
if "result" in response:
|
|
37
|
+
return assoc(response, "result", AttributeDict.recursive(response["result"]))
|
|
38
|
+
elif "params" in response and "result" in response["params"]:
|
|
39
|
+
# this is a subscription response
|
|
40
|
+
return assoc(
|
|
41
|
+
response,
|
|
42
|
+
"params",
|
|
43
|
+
assoc(
|
|
44
|
+
response["params"],
|
|
45
|
+
"result",
|
|
46
|
+
AttributeDict.recursive(response["params"]["result"]),
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
else:
|
|
50
|
+
return response
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AttributeDictMiddleware(Web3Middleware, ABC):
|
|
35
54
|
"""
|
|
36
55
|
Converts any result which is a dictionary into an `AttributeDict`.
|
|
37
56
|
|
|
@@ -39,9 +58,7 @@ def attrdict_middleware(
|
|
|
39
58
|
(e.g. my_attribute_dict.property1) will not preserve typing.
|
|
40
59
|
"""
|
|
41
60
|
|
|
42
|
-
def
|
|
43
|
-
response = make_request(method, params)
|
|
44
|
-
|
|
61
|
+
def response_processor(self, method: "RPCEndpoint", response: "RPCResponse") -> Any:
|
|
45
62
|
if "result" in response:
|
|
46
63
|
return assoc(
|
|
47
64
|
response, "result", AttributeDict.recursive(response["result"])
|
|
@@ -49,27 +66,14 @@ def attrdict_middleware(
|
|
|
49
66
|
else:
|
|
50
67
|
return response
|
|
51
68
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# --- async --- #
|
|
56
|
-
|
|
69
|
+
# -- async -- #
|
|
57
70
|
|
|
58
|
-
async def
|
|
59
|
-
|
|
60
|
-
) ->
|
|
61
|
-
|
|
62
|
-
Converts any result which is a dictionary into an `AttributeDict`.
|
|
63
|
-
|
|
64
|
-
Note: Accessing `AttributeDict` properties via attribute
|
|
65
|
-
(e.g. my_attribute_dict.property1) will not preserve typing.
|
|
66
|
-
"""
|
|
67
|
-
|
|
68
|
-
async def middleware(method: RPCEndpoint, params: Any) -> Optional[RPCResponse]:
|
|
69
|
-
response = await make_request(method, params)
|
|
70
|
-
if async_w3.provider.has_persistent_connection:
|
|
71
|
+
async def async_response_processor(
|
|
72
|
+
self, method: "RPCEndpoint", response: "RPCResponse"
|
|
73
|
+
) -> Any:
|
|
74
|
+
if self._w3.provider.has_persistent_connection:
|
|
71
75
|
# asynchronous response processing
|
|
72
|
-
provider = cast("PersistentConnectionProvider",
|
|
76
|
+
provider = cast("PersistentConnectionProvider", self._w3.provider)
|
|
73
77
|
provider._request_processor.append_middleware_response_processor(
|
|
74
78
|
response, _handle_async_response
|
|
75
79
|
)
|
|
@@ -77,22 +81,5 @@ async def async_attrdict_middleware(
|
|
|
77
81
|
else:
|
|
78
82
|
return _handle_async_response(response)
|
|
79
83
|
|
|
80
|
-
return middleware
|
|
81
|
-
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
if "result" in response:
|
|
85
|
-
return assoc(response, "result", AttributeDict.recursive(response["result"]))
|
|
86
|
-
elif "params" in response and "result" in response["params"]:
|
|
87
|
-
# this is a subscription response
|
|
88
|
-
return assoc(
|
|
89
|
-
response,
|
|
90
|
-
"params",
|
|
91
|
-
assoc(
|
|
92
|
-
response["params"],
|
|
93
|
-
"result",
|
|
94
|
-
AttributeDict.recursive(response["params"]["result"]),
|
|
95
|
-
),
|
|
96
|
-
)
|
|
97
|
-
else:
|
|
98
|
-
return response
|
|
85
|
+
AttributeDictMiddleware = AttributeDictMiddleware
|
web3/middleware/base.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
from abc import (
|
|
2
|
+
abstractmethod,
|
|
3
|
+
)
|
|
4
|
+
from typing import (
|
|
5
|
+
TYPE_CHECKING,
|
|
6
|
+
Any,
|
|
7
|
+
List,
|
|
8
|
+
Tuple,
|
|
9
|
+
Type,
|
|
10
|
+
Union,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from web3.datastructures import (
|
|
14
|
+
NamedElementOnion,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from web3 import ( # noqa: F401
|
|
19
|
+
AsyncWeb3,
|
|
20
|
+
Web3,
|
|
21
|
+
)
|
|
22
|
+
from web3.types import ( # noqa: F401
|
|
23
|
+
AsyncMakeBatchRequestFn,
|
|
24
|
+
AsyncMakeRequestFn,
|
|
25
|
+
MakeBatchRequestFn,
|
|
26
|
+
MakeRequestFn,
|
|
27
|
+
RPCEndpoint,
|
|
28
|
+
RPCResponse,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Web3Middleware:
|
|
33
|
+
"""
|
|
34
|
+
Base class for web3.py middleware. This class is not meant to be used directly,
|
|
35
|
+
but instead inherited from.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
_w3: Union["AsyncWeb3", "Web3"]
|
|
39
|
+
|
|
40
|
+
def __init__(self, w3: Union["AsyncWeb3", "Web3"]) -> None:
|
|
41
|
+
self._w3 = w3
|
|
42
|
+
|
|
43
|
+
# -- sync -- #
|
|
44
|
+
|
|
45
|
+
def wrap_make_request(self, make_request: "MakeRequestFn") -> "MakeRequestFn":
|
|
46
|
+
def middleware(method: "RPCEndpoint", params: Any) -> "RPCResponse":
|
|
47
|
+
method, params = self.request_processor(method, params)
|
|
48
|
+
return self.response_processor(method, make_request(method, params))
|
|
49
|
+
|
|
50
|
+
return middleware
|
|
51
|
+
|
|
52
|
+
def wrap_make_batch_request(
|
|
53
|
+
self, make_batch_request: "MakeBatchRequestFn"
|
|
54
|
+
) -> "MakeBatchRequestFn":
|
|
55
|
+
def middleware(
|
|
56
|
+
requests_info: List[Tuple["RPCEndpoint", Any]]
|
|
57
|
+
) -> List["RPCResponse"]:
|
|
58
|
+
req_processed = [
|
|
59
|
+
self.request_processor(method, params)
|
|
60
|
+
for (method, params) in requests_info
|
|
61
|
+
]
|
|
62
|
+
responses = make_batch_request(req_processed)
|
|
63
|
+
methods, _params = zip(*req_processed)
|
|
64
|
+
formatted_responses = [
|
|
65
|
+
self.response_processor(m, r) for m, r in zip(methods, responses)
|
|
66
|
+
]
|
|
67
|
+
return formatted_responses
|
|
68
|
+
|
|
69
|
+
return middleware
|
|
70
|
+
|
|
71
|
+
def request_processor(self, method: "RPCEndpoint", params: Any) -> Any:
|
|
72
|
+
return method, params
|
|
73
|
+
|
|
74
|
+
def response_processor(
|
|
75
|
+
self, method: "RPCEndpoint", response: "RPCResponse"
|
|
76
|
+
) -> "RPCResponse":
|
|
77
|
+
return response
|
|
78
|
+
|
|
79
|
+
# -- async -- #
|
|
80
|
+
|
|
81
|
+
async def async_wrap_make_request(
|
|
82
|
+
self, make_request: "AsyncMakeRequestFn"
|
|
83
|
+
) -> "AsyncMakeRequestFn":
|
|
84
|
+
async def middleware(method: "RPCEndpoint", params: Any) -> "RPCResponse":
|
|
85
|
+
method, params = await self.async_request_processor(method, params)
|
|
86
|
+
return await self.async_response_processor(
|
|
87
|
+
method,
|
|
88
|
+
await make_request(method, params),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
return middleware
|
|
92
|
+
|
|
93
|
+
async def async_wrap_make_batch_request(
|
|
94
|
+
self, make_batch_request: "AsyncMakeBatchRequestFn"
|
|
95
|
+
) -> "AsyncMakeBatchRequestFn":
|
|
96
|
+
async def middleware(
|
|
97
|
+
requests_info: List[Tuple["RPCEndpoint", Any]]
|
|
98
|
+
) -> List["RPCResponse"]:
|
|
99
|
+
req_processed = [
|
|
100
|
+
await self.async_request_processor(method, params)
|
|
101
|
+
for (method, params) in requests_info
|
|
102
|
+
]
|
|
103
|
+
responses = await make_batch_request(req_processed)
|
|
104
|
+
methods, _params = zip(*req_processed)
|
|
105
|
+
formatted_responses = [
|
|
106
|
+
await self.async_response_processor(m, r)
|
|
107
|
+
for m, r in zip(methods, responses)
|
|
108
|
+
]
|
|
109
|
+
return formatted_responses
|
|
110
|
+
|
|
111
|
+
return middleware
|
|
112
|
+
|
|
113
|
+
async def async_request_processor(
|
|
114
|
+
self,
|
|
115
|
+
method: "RPCEndpoint",
|
|
116
|
+
params: Any,
|
|
117
|
+
) -> Any:
|
|
118
|
+
return method, params
|
|
119
|
+
|
|
120
|
+
async def async_response_processor(
|
|
121
|
+
self,
|
|
122
|
+
method: "RPCEndpoint",
|
|
123
|
+
response: "RPCResponse",
|
|
124
|
+
) -> "RPCResponse":
|
|
125
|
+
return response
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class Web3MiddlewareBuilder(Web3Middleware):
|
|
129
|
+
@staticmethod
|
|
130
|
+
@abstractmethod
|
|
131
|
+
def build(
|
|
132
|
+
w3: Union["AsyncWeb3", "Web3"],
|
|
133
|
+
*args: Any,
|
|
134
|
+
**kwargs: Any,
|
|
135
|
+
) -> Web3Middleware:
|
|
136
|
+
"""
|
|
137
|
+
Implementation should initialize the middleware class that implements it,
|
|
138
|
+
load it with any of the necessary properties that it needs for processing,
|
|
139
|
+
and curry for the ``w3`` argument since it isn't initially present when building
|
|
140
|
+
the middleware.
|
|
141
|
+
|
|
142
|
+
example implementation:
|
|
143
|
+
|
|
144
|
+
```py
|
|
145
|
+
class MyMiddleware(Web3BuilderMiddleware):
|
|
146
|
+
internal_property: str = None
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
@curry
|
|
150
|
+
def builder(user_provided_argument, w3):
|
|
151
|
+
middleware = MyMiddleware(w3)
|
|
152
|
+
middleware.internal_property = user_provided_argument
|
|
153
|
+
return middleware
|
|
154
|
+
|
|
155
|
+
def request_processor(self, method, params):
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
def response_processor(self, method, response):
|
|
159
|
+
...
|
|
160
|
+
|
|
161
|
+
construct_my_middleware = MyMiddleware.builder
|
|
162
|
+
|
|
163
|
+
w3 = Web3(provider)
|
|
164
|
+
my_middleware = construct_my_middleware("my argument")
|
|
165
|
+
w3.middleware_onion.inject(my_middleware, layer=0)
|
|
166
|
+
```
|
|
167
|
+
"""
|
|
168
|
+
raise NotImplementedError("Must be implemented by subclasses")
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# --- type definitions --- #
|
|
172
|
+
|
|
173
|
+
Middleware = Type[Web3Middleware]
|
|
174
|
+
MiddlewareOnion = NamedElementOnion[str, Middleware]
|