web3 6.20.3__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.3.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.3.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.3.dist-info/METADATA +0 -104
- web3-6.20.3.dist-info/RECORD +0 -283
- web3-6.20.3.dist-info/entry_points.txt +0 -2
- /web3/_utils/{function_identifiers.py → abi_element_identifiers.py} +0 -0
- {web3-6.20.3.dist-info → web3-7.0.0.dist-info}/WHEEL +0 -0
web3/middleware/signing.py
CHANGED
|
@@ -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
|
|
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
|
-
"""
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
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
|
-
|
|
190
|
+
return (
|
|
191
|
+
RPCEndpoint("eth_sendRawTransaction"),
|
|
192
|
+
[raw_tx.hex()],
|
|
193
|
+
)
|
|
189
194
|
|
|
195
|
+
# -- async -- #
|
|
190
196
|
|
|
191
|
-
async def
|
|
192
|
-
|
|
193
|
-
|
|
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
|
-
|
|
207
|
-
|
|
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
|
-
|
|
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 (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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
|
+
)
|
web3/middleware/stalecheck.py
CHANGED
|
@@ -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
|
-
|
|
39
|
-
allowable_delay: int
|
|
40
|
-
skip_stalecheck_for_methods: Collection[str]
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
90
|
-
middleware with a method call.
|
|
78
|
+
return method, params
|
|
91
79
|
|
|
92
|
-
|
|
80
|
+
# -- async -- #
|
|
93
81
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
93
|
+
return method, params
|
web3/middleware/validation.py
CHANGED
|
@@ -33,11 +33,9 @@ from web3.exceptions import (
|
|
|
33
33
|
Web3ValidationError,
|
|
34
34
|
)
|
|
35
35
|
from web3.middleware.formatting import (
|
|
36
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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",
|
|
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",
|
|
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
|
|
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.
|
|
141
|
+
return await async_w3.manager.socket_request(method_str, params)
|
|
105
142
|
except Exception as e:
|
|
106
|
-
if
|
|
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
|
|
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__(
|
|
195
|
+
method_class.__get__(module=self)()
|
|
152
196
|
if method_class.is_property
|
|
153
|
-
else method_class.__get__(
|
|
197
|
+
else method_class.__get__(module=self)
|
|
154
198
|
)
|
|
155
199
|
setattr(self, method_name, klass)
|
web3/providers/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from .async_base import (
|
|
2
2
|
AsyncBaseProvider,
|
|
3
3
|
)
|
|
4
|
-
from .
|
|
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 .
|
|
22
|
-
|
|
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
|
-
"
|
|
44
|
-
"WebsocketProviderV2",
|
|
48
|
+
"WebSocketProvider",
|
|
45
49
|
]
|