eth-prototype 1.1.0__tar.gz → 1.2.0__tar.gz
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.
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/PKG-INFO +3 -3
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/setup.cfg +2 -2
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/eth_prototype.egg-info/PKG-INFO +3 -3
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/eth_prototype.egg-info/SOURCES.txt +1 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/eth_prototype.egg-info/requires.txt +2 -2
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/aa_bundler.py +38 -19
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/w3wrappers.py +18 -9
- eth_prototype-1.2.0/tests/hardhat-project/contracts/EventLauncher.sol +16 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_aa_bundler.py +12 -11
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_w3.py +29 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.coveragerc +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.github/workflows/publish.yaml +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.github/workflows/test.yaml +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.gitignore +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.isort.cfg +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.pre-commit-config.yaml +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/.readthedocs.yml +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/AUTHORS.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/CHANGELOG.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/LICENSE.txt +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/README.md +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/Makefile +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/_static/.gitignore +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/authors.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/changelog.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/conf.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/index.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/license.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/readme.rst +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/docs/requirements.txt +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/pyproject.toml +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/setup.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/eth_prototype.egg-info/dependency_links.txt +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/eth_prototype.egg-info/not-zip-safe +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/eth_prototype.egg-info/top_level.txt +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/__init__.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/build_artifacts.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/contracts.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/defender_relay.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/wadray.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/src/ethproto/wrappers.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/conftest.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/README.md +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/artifacts2/TestCurrency.sol/TestCurrency.json +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/Count.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/Counter.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/CounterUpgradeable.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/CounterUpgradeableWithLibrary.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/CounterWithLibrary.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/Datatypes.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/TestCurrency.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/TestCurrencyUUPS.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/TestNFT.sol +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/hardhat.config.js +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/package-lock.json +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/package.json +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_build_artifacts.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_contracts.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_defender.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_time_control.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/test_wadray.py +0 -0
- {eth_prototype-1.1.0 → eth_prototype-1.2.0}/tox.ini +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: eth-prototype
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.2.0
|
4
4
|
Summary: Prototype Ethereum Smart Contracts in Python
|
5
5
|
Home-page: https://github.com/gnarvaja/eth-prototype
|
6
6
|
Author: Guillermo M. Narvaja
|
@@ -20,7 +20,7 @@ Requires-Dist: requests
|
|
20
20
|
Requires-Dist: hexbytes
|
21
21
|
Requires-Dist: importlib-metadata; python_version < "3.8"
|
22
22
|
Provides-Extra: web3
|
23
|
-
Requires-Dist: web3==
|
23
|
+
Requires-Dist: web3==7.*; extra == "web3"
|
24
24
|
Provides-Extra: defender
|
25
25
|
Requires-Dist: boto3; extra == "defender"
|
26
26
|
Provides-Extra: gmpy2
|
@@ -30,7 +30,7 @@ Requires-Dist: setuptools; extra == "testing"
|
|
30
30
|
Requires-Dist: pytest; extra == "testing"
|
31
31
|
Requires-Dist: gmpy2; extra == "testing"
|
32
32
|
Requires-Dist: pytest-cov; extra == "testing"
|
33
|
-
Requires-Dist: web3[tester]==
|
33
|
+
Requires-Dist: web3[tester]==7.*; extra == "testing"
|
34
34
|
Requires-Dist: boto3; extra == "testing"
|
35
35
|
|
36
36
|
# eth-prototype
|
@@ -35,7 +35,7 @@ exclude =
|
|
35
35
|
|
36
36
|
[options.extras_require]
|
37
37
|
web3 =
|
38
|
-
web3==
|
38
|
+
web3==7.*
|
39
39
|
defender =
|
40
40
|
boto3
|
41
41
|
gmpy2 =
|
@@ -45,7 +45,7 @@ testing =
|
|
45
45
|
pytest
|
46
46
|
gmpy2
|
47
47
|
pytest-cov
|
48
|
-
web3[tester]==
|
48
|
+
web3[tester]==7.*
|
49
49
|
boto3
|
50
50
|
|
51
51
|
[options.entry_points]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: eth-prototype
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.2.0
|
4
4
|
Summary: Prototype Ethereum Smart Contracts in Python
|
5
5
|
Home-page: https://github.com/gnarvaja/eth-prototype
|
6
6
|
Author: Guillermo M. Narvaja
|
@@ -20,7 +20,7 @@ Requires-Dist: requests
|
|
20
20
|
Requires-Dist: hexbytes
|
21
21
|
Requires-Dist: importlib-metadata; python_version < "3.8"
|
22
22
|
Provides-Extra: web3
|
23
|
-
Requires-Dist: web3==
|
23
|
+
Requires-Dist: web3==7.*; extra == "web3"
|
24
24
|
Provides-Extra: defender
|
25
25
|
Requires-Dist: boto3; extra == "defender"
|
26
26
|
Provides-Extra: gmpy2
|
@@ -30,7 +30,7 @@ Requires-Dist: setuptools; extra == "testing"
|
|
30
30
|
Requires-Dist: pytest; extra == "testing"
|
31
31
|
Requires-Dist: gmpy2; extra == "testing"
|
32
32
|
Requires-Dist: pytest-cov; extra == "testing"
|
33
|
-
Requires-Dist: web3[tester]==
|
33
|
+
Requires-Dist: web3[tester]==7.*; extra == "testing"
|
34
34
|
Requires-Dist: boto3; extra == "testing"
|
35
35
|
|
36
36
|
# eth-prototype
|
@@ -55,6 +55,7 @@ tests/hardhat-project/contracts/CounterUpgradeable.sol
|
|
55
55
|
tests/hardhat-project/contracts/CounterUpgradeableWithLibrary.sol
|
56
56
|
tests/hardhat-project/contracts/CounterWithLibrary.sol
|
57
57
|
tests/hardhat-project/contracts/Datatypes.sol
|
58
|
+
tests/hardhat-project/contracts/EventLauncher.sol
|
58
59
|
tests/hardhat-project/contracts/TestCurrency.sol
|
59
60
|
tests/hardhat-project/contracts/TestCurrencyUUPS.sol
|
60
61
|
tests/hardhat-project/contracts/TestNFT.sol
|
@@ -1,15 +1,17 @@
|
|
1
1
|
import random
|
2
|
-
from warnings import warn
|
3
2
|
from enum import Enum
|
4
|
-
import
|
3
|
+
from warnings import warn
|
4
|
+
|
5
5
|
from environs import Env
|
6
6
|
from eth_abi import encode
|
7
7
|
from eth_account import Account
|
8
8
|
from eth_account.messages import encode_defunct
|
9
|
+
from eth_utils import add_0x_prefix
|
9
10
|
from hexbytes import HexBytes
|
10
11
|
from web3 import Web3
|
11
|
-
from .
|
12
|
+
from web3.constants import ADDRESS_ZERO
|
12
13
|
|
14
|
+
from .contracts import RevertError
|
13
15
|
|
14
16
|
env = Env()
|
15
17
|
|
@@ -17,6 +19,9 @@ AA_BUNDLER_SENDER = env.str("AA_BUNDLER_SENDER", None)
|
|
17
19
|
AA_BUNDLER_ENTRYPOINT = env.str("AA_BUNDLER_ENTRYPOINT", "0x0000000071727De22E5E9d8BAf0edAc6f37da032")
|
18
20
|
AA_BUNDLER_EXECUTOR_PK = env.str("AA_BUNDLER_EXECUTOR_PK", None)
|
19
21
|
AA_BUNDLER_PROVIDER = env.str("AA_BUNDLER_PROVIDER", "alchemy")
|
22
|
+
AA_BUNDLER_GAS_LIMIT_FACTOR = env.float("AA_BUNDLER_GAS_LIMIT_FACTOR", 1)
|
23
|
+
AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR", 1)
|
24
|
+
AA_BUNDLER_BASE_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_BASE_GAS_PRICE_FACTOR", 1)
|
20
25
|
|
21
26
|
NonceMode = Enum(
|
22
27
|
"NonceMode",
|
@@ -51,8 +56,8 @@ RANDOM_NONCE_KEY = None
|
|
51
56
|
|
52
57
|
|
53
58
|
def pack_two(a, b):
|
54
|
-
a = HexBytes(a).hex()
|
55
|
-
b = HexBytes(b).hex()
|
59
|
+
a = HexBytes(a).hex()
|
60
|
+
b = HexBytes(b).hex()
|
56
61
|
return "0x" + a.zfill(32) + b.zfill(32)
|
57
62
|
|
58
63
|
|
@@ -98,23 +103,23 @@ def hash_packed_user_operation_only(packed_user_op):
|
|
98
103
|
hash_paymaster_and_data,
|
99
104
|
],
|
100
105
|
).hex()
|
101
|
-
)
|
106
|
+
)
|
102
107
|
|
103
108
|
|
104
109
|
def hash_packed_user_operation(packed_user_op, chain_id, entry_point):
|
105
110
|
return Web3.keccak(
|
106
111
|
hexstr=encode(
|
107
112
|
["bytes32", "address", "uint256"],
|
108
|
-
[
|
113
|
+
[hash_packed_user_operation_only(packed_user_op), entry_point, chain_id],
|
109
114
|
).hex()
|
110
|
-
)
|
115
|
+
)
|
111
116
|
|
112
117
|
|
113
118
|
def sign_user_operation(private_key, user_operation, chain_id, entry_point):
|
114
119
|
packed_user_op = pack_user_operation(user_operation)
|
115
120
|
hash = hash_packed_user_operation(packed_user_op, chain_id, entry_point)
|
116
|
-
signature = Account.sign_message(encode_defunct(hexstr=hash), private_key)
|
117
|
-
return signature.signature
|
121
|
+
signature = Account.sign_message(encode_defunct(hexstr=hash.hex()), private_key)
|
122
|
+
return signature.signature
|
118
123
|
|
119
124
|
|
120
125
|
def make_nonce(nonce_key, nonce):
|
@@ -147,7 +152,7 @@ def get_nonce_and_key(w3, tx, nonce_mode, entry_point=AA_BUNDLER_ENTRYPOINT, fet
|
|
147
152
|
|
148
153
|
if nonce is None:
|
149
154
|
if fetch or nonce_mode == NonceMode.FIXED_KEY_FETCH_ALWAYS:
|
150
|
-
nonce = fetch_nonce(w3, tx
|
155
|
+
nonce = fetch_nonce(w3, get_sender(tx), entry_point, nonce_key)
|
151
156
|
elif nonce_key not in NONCE_CACHE:
|
152
157
|
nonce = 0
|
153
158
|
else:
|
@@ -168,7 +173,16 @@ def handle_response_error(resp, w3, tx, retry_nonce):
|
|
168
173
|
|
169
174
|
def get_base_fee(w3):
|
170
175
|
blk = w3.eth.get_block("latest")
|
171
|
-
return blk["baseFeePerGas"]
|
176
|
+
return int(_to_uint(blk["baseFeePerGas"]) * AA_BUNDLER_BASE_GAS_PRICE_FACTOR)
|
177
|
+
|
178
|
+
|
179
|
+
def get_sender(tx):
|
180
|
+
if "from" not in tx or tx["from"] == ADDRESS_ZERO:
|
181
|
+
if AA_BUNDLER_SENDER is None:
|
182
|
+
raise RuntimeError("Must define AA_BUNDLER_SENDER or send 'from' in the TX")
|
183
|
+
return AA_BUNDLER_SENDER
|
184
|
+
else:
|
185
|
+
return tx["from"]
|
172
186
|
|
173
187
|
|
174
188
|
def send_transaction(w3, tx, retry_nonce=None):
|
@@ -185,7 +199,7 @@ def send_transaction(w3, tx, retry_nonce=None):
|
|
185
199
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c"
|
186
200
|
)
|
187
201
|
user_operation = {
|
188
|
-
"sender": tx
|
202
|
+
"sender": get_sender(tx),
|
189
203
|
"nonce": hex(make_nonce(nonce_key, nonce)),
|
190
204
|
"callData": call_data,
|
191
205
|
"signature": dummy_signature,
|
@@ -203,9 +217,12 @@ def send_transaction(w3, tx, retry_nonce=None):
|
|
203
217
|
resp = w3.provider.make_request("rundler_maxPriorityFeePerGas", [])
|
204
218
|
if "error" in resp:
|
205
219
|
raise RevertError(resp["error"]["message"])
|
206
|
-
max_priority_fee_per_gas = resp["result"]
|
207
|
-
user_operation["maxPriorityFeePerGas"] = max_priority_fee_per_gas
|
208
|
-
user_operation["maxFeePerGas"] = hex(
|
220
|
+
max_priority_fee_per_gas = int(_to_uint(resp["result"]) * AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR)
|
221
|
+
user_operation["maxPriorityFeePerGas"] = hex(max_priority_fee_per_gas)
|
222
|
+
user_operation["maxFeePerGas"] = hex(max_priority_fee_per_gas + get_base_fee(w3))
|
223
|
+
user_operation["callGasLimit"] = hex(
|
224
|
+
int(_to_uint(user_operation["callGasLimit"]) * AA_BUNDLER_GAS_LIMIT_FACTOR)
|
225
|
+
)
|
209
226
|
elif AA_BUNDLER_PROVIDER == "gelato":
|
210
227
|
user_operation.update(
|
211
228
|
{
|
@@ -216,8 +233,10 @@ def send_transaction(w3, tx, retry_nonce=None):
|
|
216
233
|
"maxPriorityFeePerGas": "0x00",
|
217
234
|
}
|
218
235
|
)
|
219
|
-
user_operation["signature"] =
|
220
|
-
|
236
|
+
user_operation["signature"] = add_0x_prefix(
|
237
|
+
sign_user_operation(
|
238
|
+
AA_BUNDLER_EXECUTOR_PK, user_operation, tx["chainId"], AA_BUNDLER_ENTRYPOINT
|
239
|
+
).hex()
|
221
240
|
)
|
222
241
|
# Remove paymaster related fields
|
223
242
|
user_operation.pop("paymaster", None)
|
@@ -231,4 +250,4 @@ def send_transaction(w3, tx, retry_nonce=None):
|
|
231
250
|
|
232
251
|
# Store nonce in the cache, so next time uses a new nonce
|
233
252
|
NONCE_CACHE[nonce_key] = nonce + 1
|
234
|
-
return resp["result"]
|
253
|
+
return {"userOpHash": resp["result"]}
|
@@ -9,7 +9,7 @@ from eth_utils.abi import event_abi_to_log_topic
|
|
9
9
|
from hexbytes import HexBytes
|
10
10
|
from web3.contract import Contract
|
11
11
|
from web3.exceptions import ContractLogicError, ExtraDataLengthError
|
12
|
-
from web3.middleware import
|
12
|
+
from web3.middleware import ExtraDataToPOAMiddleware
|
13
13
|
|
14
14
|
from .build_artifacts import ArtifactLibrary
|
15
15
|
from .contracts import RevertError
|
@@ -49,14 +49,21 @@ class W3TimeControl:
|
|
49
49
|
return self.w3.eth.get_block("latest").timestamp
|
50
50
|
|
51
51
|
|
52
|
-
def register_w3_provider(provider_key="w3", tester=None, provider_kwargs=
|
52
|
+
def register_w3_provider(provider_key="w3", w3=None, tester=None, provider_kwargs=None):
|
53
|
+
if w3 is not None and tester is not None:
|
54
|
+
raise ValueError("Cannot inject w3 and use tester at the same time")
|
55
|
+
|
56
|
+
provider_kwargs = provider_kwargs or {}
|
53
57
|
if tester is None:
|
54
58
|
try:
|
55
59
|
import eth_tester # noqa
|
56
60
|
except ImportError:
|
57
61
|
tester = False
|
58
62
|
|
59
|
-
if
|
63
|
+
if w3 is not None:
|
64
|
+
# the provided w3 instance takes precedence over all other args
|
65
|
+
pass
|
66
|
+
elif tester:
|
60
67
|
from web3 import Web3
|
61
68
|
|
62
69
|
w3 = Web3(Web3.EthereumTesterProvider())
|
@@ -68,9 +75,9 @@ def register_w3_provider(provider_key="w3", tester=None, provider_kwargs={}):
|
|
68
75
|
try:
|
69
76
|
w3.eth.get_block("latest")
|
70
77
|
except ExtraDataLengthError:
|
71
|
-
w3.middleware_onion.inject(
|
78
|
+
w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
|
72
79
|
elif W3_POA == "yes":
|
73
|
-
w3.middleware_onion.inject(
|
80
|
+
w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
|
74
81
|
|
75
82
|
# If address_book not provided and there are envs with W3_ADDRESS_BOOK_PREFIX,
|
76
83
|
# use W3EnvAddressBook
|
@@ -375,6 +382,8 @@ class W3ETHCall(ETHCall):
|
|
375
382
|
def normalize_receipt(self, wrapper, receipt):
|
376
383
|
if W3_TRANSACT_MODE == "defender-async":
|
377
384
|
return receipt # Don't do anything because the receipt is just a dict of not-yet-mined tx
|
385
|
+
elif W3_TRANSACT_MODE == "aa-bundler-async":
|
386
|
+
return receipt # Don't do anything because the receipt is just a dict of {"userOpHash": "..."}
|
378
387
|
return ReceiptWrapper(receipt, wrapper.contract)
|
379
388
|
|
380
389
|
def _handle_exception(self, err):
|
@@ -442,7 +451,7 @@ class W3Provider(BaseProvider):
|
|
442
451
|
def get_events(self, eth_wrapper, event_name, filter_kwargs={}):
|
443
452
|
"""Returns a list of events given a filter, like this:
|
444
453
|
|
445
|
-
>>> provider.get_events(currencywrapper, "Transfer", dict(
|
454
|
+
>>> provider.get_events(currencywrapper, "Transfer", dict(from_block=0))
|
446
455
|
[AttributeDict({
|
447
456
|
'args': AttributeDict(
|
448
457
|
{'from': '0x0000000000000000000000000000000000000000',
|
@@ -461,8 +470,8 @@ class W3Provider(BaseProvider):
|
|
461
470
|
"""
|
462
471
|
contract = eth_wrapper.contract
|
463
472
|
event = getattr(contract.events, event_name)
|
464
|
-
if "
|
465
|
-
filter_kwargs["
|
473
|
+
if "from_block" not in filter_kwargs:
|
474
|
+
filter_kwargs["from_block"] = self.get_first_block(eth_wrapper)
|
466
475
|
event_filter = event.create_filter(**filter_kwargs)
|
467
476
|
return event_filter.get_all_entries()
|
468
477
|
|
@@ -488,7 +497,7 @@ class W3Provider(BaseProvider):
|
|
488
497
|
constructor_params, init_params = init_params
|
489
498
|
real_contract = self.construct(eth_contract, constructor_params, {"from": eth_wrapper.owner})
|
490
499
|
ERC1967Proxy = self.get_contract_factory("ERC1967Proxy")
|
491
|
-
init_data = eth_contract.
|
500
|
+
init_data = eth_contract.encode_abi(abi_element_identifier="initialize", args=init_params)
|
492
501
|
proxy_contract = self.construct(
|
493
502
|
ERC1967Proxy,
|
494
503
|
(real_contract.address, init_data),
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
2
|
+
pragma solidity ^0.8.9;
|
3
|
+
|
4
|
+
contract EventLauncher {
|
5
|
+
event Event1(uint256 value);
|
6
|
+
|
7
|
+
event Event2(uint256 value);
|
8
|
+
|
9
|
+
function launchEvent1(uint256 value) public {
|
10
|
+
emit Event1(value);
|
11
|
+
}
|
12
|
+
|
13
|
+
function launchEvent2(uint256 value) public {
|
14
|
+
emit Event2(value);
|
15
|
+
}
|
16
|
+
}
|
@@ -1,7 +1,9 @@
|
|
1
|
+
from unittest.mock import MagicMock, patch
|
2
|
+
|
1
3
|
from hexbytes import HexBytes
|
2
|
-
from ethproto import aa_bundler
|
3
4
|
from web3.constants import HASH_ZERO
|
4
|
-
|
5
|
+
|
6
|
+
from ethproto import aa_bundler
|
5
7
|
|
6
8
|
|
7
9
|
def test_pack_two():
|
@@ -58,16 +60,15 @@ def test_pack_user_operation():
|
|
58
60
|
def test_hash_packed_user_operation():
|
59
61
|
packed = aa_bundler.pack_user_operation(user_operation)
|
60
62
|
hash = aa_bundler.hash_packed_user_operation_only(packed)
|
61
|
-
assert hash == "0xa2c19765d18b0d690c05b20061bd23d066201aff1833a51bd28af115fbd4bcd9"
|
63
|
+
assert hash == HexBytes("0xa2c19765d18b0d690c05b20061bd23d066201aff1833a51bd28af115fbd4bcd9")
|
62
64
|
hash = aa_bundler.hash_packed_user_operation(packed, CHAIN_ID, ENTRYPOINT)
|
63
|
-
assert hash == "0xb365ad4d366e9081718e926912da7a78a2faae592286fda0cc11923bd141b7cf"
|
65
|
+
assert hash == HexBytes("0xb365ad4d366e9081718e926912da7a78a2faae592286fda0cc11923bd141b7cf")
|
64
66
|
|
65
67
|
|
66
68
|
def test_sign_user_operation():
|
67
69
|
signature = aa_bundler.sign_user_operation(TEST_PRIVATE_KEY, user_operation, CHAIN_ID, ENTRYPOINT)
|
68
|
-
assert (
|
69
|
-
|
70
|
-
== "0xb9b872bfe4e90f4628e8ec24879a5b01045f91da8457f3ce2b417d2e5774b508261ec1147a820e75a141cb61b884a78d7e88996ceddafb9a7016cfe7a48a1f4f1b" # noqa
|
70
|
+
assert signature == HexBytes(
|
71
|
+
"0xb9b872bfe4e90f4628e8ec24879a5b01045f91da8457f3ce2b417d2e5774b508261ec1147a820e75a141cb61b884a78d7e88996ceddafb9a7016cfe7a48a1f4f1b" # noqa
|
71
72
|
)
|
72
73
|
|
73
74
|
|
@@ -75,9 +76,8 @@ def test_sign_user_operation_gas_diff():
|
|
75
76
|
user_operation_2 = dict(user_operation)
|
76
77
|
user_operation_2["maxPriorityFeePerGas"] -= 1
|
77
78
|
signature = aa_bundler.sign_user_operation(TEST_PRIVATE_KEY, user_operation_2, CHAIN_ID, ENTRYPOINT)
|
78
|
-
assert (
|
79
|
-
|
80
|
-
== "0x8162479d2dbd18d7fe93a2f51e283021d6e4eae4f57d20cdd553042723a0b0ea690ab3903d45126b0047da08ab53dfdf86656e4f258ac4936ba96a759ccb77f61b" # noqa
|
79
|
+
assert signature == HexBytes(
|
80
|
+
"0x8162479d2dbd18d7fe93a2f51e283021d6e4eae4f57d20cdd553042723a0b0ea690ab3903d45126b0047da08ab53dfdf86656e4f258ac4936ba96a759ccb77f61b" # noqa
|
81
81
|
)
|
82
82
|
|
83
83
|
|
@@ -175,6 +175,7 @@ def test_get_nonce_with_local_cache(fetch_nonce_mock, randint_mock):
|
|
175
175
|
fetch_nonce_mock.assert_not_called()
|
176
176
|
|
177
177
|
|
178
|
+
@patch.object(aa_bundler, "AA_BUNDLER_NONCE_MODE", new=aa_bundler.NonceMode.FIXED_KEY_LOCAL_NONCE)
|
178
179
|
@patch.object(aa_bundler, "get_base_fee")
|
179
180
|
def test_send_transaction(get_base_fee_mock):
|
180
181
|
get_base_fee_mock.return_value = 0
|
@@ -239,4 +240,4 @@ def test_send_transaction(get_base_fee_mock):
|
|
239
240
|
ret = aa_bundler.send_transaction(w3, tx)
|
240
241
|
get_base_fee_mock.assert_called_once_with(w3)
|
241
242
|
assert aa_bundler.NONCE_CACHE[0] == 1
|
242
|
-
assert ret == "0xa950a17ca1ed83e974fb1aa227360a007cb65f566518af117ffdbb04d8d2d524"
|
243
|
+
assert ret == {"userOpHash": "0xa950a17ca1ed83e974fb1aa227360a007cb65f566518af117ffdbb04d8d2d524"}
|
@@ -77,3 +77,32 @@ def test_wrapper_build_from_def():
|
|
77
77
|
assert counter.value() == 0
|
78
78
|
counter.increase()
|
79
79
|
assert counter.value() == 1
|
80
|
+
|
81
|
+
|
82
|
+
def test_get_events():
|
83
|
+
provider = wrappers.get_provider("w3")
|
84
|
+
contract_def = provider.get_contract_def("EventLauncher")
|
85
|
+
wrapper = wrappers.ETHWrapper.build_from_def(contract_def)
|
86
|
+
|
87
|
+
launcher = wrapper()
|
88
|
+
|
89
|
+
launcher.launchEvent1(1)
|
90
|
+
|
91
|
+
cutoff_block = provider.w3.eth.get_block("latest")
|
92
|
+
launcher.launchEvent2(2)
|
93
|
+
launcher.launchEvent1(3)
|
94
|
+
|
95
|
+
all_event1 = provider.get_events(launcher, "Event1", dict(from_block=0))
|
96
|
+
assert len(all_event1) == 2
|
97
|
+
|
98
|
+
first_event1_only = provider.get_events(launcher, "Event1", dict(to_block=cutoff_block.number))
|
99
|
+
assert len(first_event1_only) == 1
|
100
|
+
assert first_event1_only[0] == all_event1[0]
|
101
|
+
|
102
|
+
last_event1_only = provider.get_events(launcher, "Event1", dict(from_block=cutoff_block.number + 1))
|
103
|
+
assert len(last_event1_only) == 1
|
104
|
+
assert last_event1_only[0] == all_event1[-1]
|
105
|
+
|
106
|
+
event2 = provider.get_events(launcher, "Event2")
|
107
|
+
assert len(event2) == 1
|
108
|
+
assert event2[0].args.value == 2
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/CounterUpgradeable.sol
RENAMED
File without changes
|
File without changes
|
{eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/CounterWithLibrary.sol
RENAMED
File without changes
|
File without changes
|
{eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/TestCurrency.sol
RENAMED
File without changes
|
{eth_prototype-1.1.0 → eth_prototype-1.2.0}/tests/hardhat-project/contracts/TestCurrencyUUPS.sol
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|