eth-prototype 1.1.0__tar.gz → 1.2.0b1__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.
Files changed (62) hide show
  1. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/PKG-INFO +3 -3
  2. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/setup.cfg +2 -2
  3. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/eth_prototype.egg-info/PKG-INFO +3 -3
  4. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/eth_prototype.egg-info/SOURCES.txt +1 -0
  5. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/eth_prototype.egg-info/requires.txt +2 -2
  6. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/aa_bundler.py +38 -19
  7. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/w3wrappers.py +9 -7
  8. eth_prototype-1.2.0b1/tests/hardhat-project/contracts/EventLauncher.sol +16 -0
  9. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_aa_bundler.py +12 -11
  10. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_w3.py +29 -0
  11. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.coveragerc +0 -0
  12. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.github/workflows/publish.yaml +0 -0
  13. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.github/workflows/test.yaml +0 -0
  14. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.gitignore +0 -0
  15. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.isort.cfg +0 -0
  16. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.pre-commit-config.yaml +0 -0
  17. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/.readthedocs.yml +0 -0
  18. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/AUTHORS.rst +0 -0
  19. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/CHANGELOG.rst +0 -0
  20. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/LICENSE.txt +0 -0
  21. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/README.md +0 -0
  22. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/Makefile +0 -0
  23. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/_static/.gitignore +0 -0
  24. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/authors.rst +0 -0
  25. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/changelog.rst +0 -0
  26. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/conf.py +0 -0
  27. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/index.rst +0 -0
  28. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/license.rst +0 -0
  29. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/readme.rst +0 -0
  30. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/docs/requirements.txt +0 -0
  31. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/pyproject.toml +0 -0
  32. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/setup.py +0 -0
  33. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/eth_prototype.egg-info/dependency_links.txt +0 -0
  34. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/eth_prototype.egg-info/not-zip-safe +0 -0
  35. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/eth_prototype.egg-info/top_level.txt +0 -0
  36. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/__init__.py +0 -0
  37. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/build_artifacts.py +0 -0
  38. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/contracts.py +0 -0
  39. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/defender_relay.py +0 -0
  40. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/wadray.py +0 -0
  41. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/src/ethproto/wrappers.py +0 -0
  42. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/conftest.py +0 -0
  43. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/README.md +0 -0
  44. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/artifacts2/TestCurrency.sol/TestCurrency.json +0 -0
  45. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/Count.sol +0 -0
  46. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/Counter.sol +0 -0
  47. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/CounterUpgradeable.sol +0 -0
  48. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/CounterUpgradeableWithLibrary.sol +0 -0
  49. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/CounterWithLibrary.sol +0 -0
  50. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/Datatypes.sol +0 -0
  51. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/TestCurrency.sol +0 -0
  52. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/TestCurrencyUUPS.sol +0 -0
  53. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/contracts/TestNFT.sol +0 -0
  54. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/hardhat.config.js +0 -0
  55. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/package-lock.json +0 -0
  56. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/hardhat-project/package.json +0 -0
  57. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_build_artifacts.py +0 -0
  58. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_contracts.py +0 -0
  59. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_defender.py +0 -0
  60. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_time_control.py +0 -0
  61. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tests/test_wadray.py +0 -0
  62. {eth_prototype-1.1.0 → eth_prototype-1.2.0b1}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: eth-prototype
3
- Version: 1.1.0
3
+ Version: 1.2.0b1
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==6.*; extra == "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]==6.*; extra == "testing"
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==6.*
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]==6.*
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.1.0
3
+ Version: 1.2.0b1
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==6.*; extra == "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]==6.*; extra == "testing"
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
@@ -17,8 +17,8 @@ setuptools
17
17
  pytest
18
18
  gmpy2
19
19
  pytest-cov
20
- web3[tester]==6.*
20
+ web3[tester]==7.*
21
21
  boto3
22
22
 
23
23
  [web3]
24
- web3==6.*
24
+ web3==7.*
@@ -1,15 +1,17 @@
1
1
  import random
2
- from warnings import warn
3
2
  from enum import Enum
4
- import requests
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 .contracts import RevertError
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()[2:]
55
- b = HexBytes(b).hex()[2:]
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
- ).hex()
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
- [HexBytes(hash_packed_user_operation_only(packed_user_op)), entry_point, chain_id],
113
+ [hash_packed_user_operation_only(packed_user_op), entry_point, chain_id],
109
114
  ).hex()
110
- ).hex()
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.hex()
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.get("from", AA_BUNDLER_SENDER), entry_point, nonce_key)
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.get("from", AA_BUNDLER_SENDER),
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(_to_uint(max_priority_fee_per_gas) + _to_uint(get_base_fee(w3)))
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"] = sign_user_operation(
220
- AA_BUNDLER_EXECUTOR_PK, user_operation, tx["chainId"], AA_BUNDLER_ENTRYPOINT
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 geth_poa_middleware
12
+ from web3.middleware import ExtraDataToPOAMiddleware
13
13
 
14
14
  from .build_artifacts import ArtifactLibrary
15
15
  from .contracts import RevertError
@@ -68,9 +68,9 @@ def register_w3_provider(provider_key="w3", tester=None, provider_kwargs={}):
68
68
  try:
69
69
  w3.eth.get_block("latest")
70
70
  except ExtraDataLengthError:
71
- w3.middleware_onion.inject(geth_poa_middleware, layer=0)
71
+ w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
72
72
  elif W3_POA == "yes":
73
- w3.middleware_onion.inject(geth_poa_middleware, layer=0)
73
+ w3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
74
74
 
75
75
  # If address_book not provided and there are envs with W3_ADDRESS_BOOK_PREFIX,
76
76
  # use W3EnvAddressBook
@@ -375,6 +375,8 @@ class W3ETHCall(ETHCall):
375
375
  def normalize_receipt(self, wrapper, receipt):
376
376
  if W3_TRANSACT_MODE == "defender-async":
377
377
  return receipt # Don't do anything because the receipt is just a dict of not-yet-mined tx
378
+ elif W3_TRANSACT_MODE == "aa-bundler-async":
379
+ return receipt # Don't do anything because the receipt is just a dict of {"userOpHash": "..."}
378
380
  return ReceiptWrapper(receipt, wrapper.contract)
379
381
 
380
382
  def _handle_exception(self, err):
@@ -442,7 +444,7 @@ class W3Provider(BaseProvider):
442
444
  def get_events(self, eth_wrapper, event_name, filter_kwargs={}):
443
445
  """Returns a list of events given a filter, like this:
444
446
 
445
- >>> provider.get_events(currencywrapper, "Transfer", dict(fromBlock=0))
447
+ >>> provider.get_events(currencywrapper, "Transfer", dict(from_block=0))
446
448
  [AttributeDict({
447
449
  'args': AttributeDict(
448
450
  {'from': '0x0000000000000000000000000000000000000000',
@@ -461,8 +463,8 @@ class W3Provider(BaseProvider):
461
463
  """
462
464
  contract = eth_wrapper.contract
463
465
  event = getattr(contract.events, event_name)
464
- if "fromBlock" not in filter_kwargs:
465
- filter_kwargs["fromBlock"] = self.get_first_block(eth_wrapper)
466
+ if "from_block" not in filter_kwargs:
467
+ filter_kwargs["from_block"] = self.get_first_block(eth_wrapper)
466
468
  event_filter = event.create_filter(**filter_kwargs)
467
469
  return event_filter.get_all_entries()
468
470
 
@@ -488,7 +490,7 @@ class W3Provider(BaseProvider):
488
490
  constructor_params, init_params = init_params
489
491
  real_contract = self.construct(eth_contract, constructor_params, {"from": eth_wrapper.owner})
490
492
  ERC1967Proxy = self.get_contract_factory("ERC1967Proxy")
491
- init_data = eth_contract.encodeABI(fn_name="initialize", args=init_params)
493
+ init_data = eth_contract.encode_abi(abi_element_identifier="initialize", args=init_params)
492
494
  proxy_contract = self.construct(
493
495
  ERC1967Proxy,
494
496
  (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
- from unittest.mock import MagicMock, patch
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
- signature
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
- signature
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