eth-prototype 1.5.1__tar.gz → 1.5.2__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 (72) hide show
  1. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/PKG-INFO +1 -1
  2. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/eth_prototype.egg-info/PKG-INFO +1 -1
  3. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/aa_bundler.py +30 -35
  4. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.coveragerc +0 -0
  5. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.github/workflows/publish.yaml +0 -0
  6. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.github/workflows/test.yaml +0 -0
  7. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.gitignore +0 -0
  8. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.isort.cfg +0 -0
  9. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.pre-commit-config.yaml +0 -0
  10. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/.readthedocs.yml +0 -0
  11. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/AUTHORS.rst +0 -0
  12. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/CHANGELOG.rst +0 -0
  13. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/LICENSE.txt +0 -0
  14. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/README.md +0 -0
  15. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/Makefile +0 -0
  16. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/_static/.gitignore +0 -0
  17. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/authors.rst +0 -0
  18. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/changelog.rst +0 -0
  19. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/conf.py +0 -0
  20. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/index.rst +0 -0
  21. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/license.rst +0 -0
  22. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/readme.rst +0 -0
  23. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/docs/requirements.txt +0 -0
  24. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/pyproject.toml +0 -0
  25. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/setup.cfg +0 -0
  26. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/setup.py +0 -0
  27. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/eth_prototype.egg-info/SOURCES.txt +0 -0
  28. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/eth_prototype.egg-info/dependency_links.txt +0 -0
  29. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/eth_prototype.egg-info/not-zip-safe +0 -0
  30. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/eth_prototype.egg-info/requires.txt +0 -0
  31. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/eth_prototype.egg-info/top_level.txt +0 -0
  32. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/__init__.py +0 -0
  33. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/build_artifacts.py +0 -0
  34. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/contracts.py +0 -0
  35. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/defender_relay.py +0 -0
  36. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/test_utils/__init__.py +0 -0
  37. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/test_utils/factories.py +0 -0
  38. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/test_utils/hardhat.py +0 -0
  39. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/test_utils/vcr_utils.py +0 -0
  40. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/w3wrappers.py +0 -0
  41. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/wadray.py +0 -0
  42. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/src/ethproto/wrappers.py +0 -0
  43. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/__init__.py +0 -0
  44. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/cassettes/test_aa_bundler/test_build_user_operation.yaml +0 -0
  45. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/cassettes/test_aa_bundler/test_build_user_operation_execute_user_op.yaml +0 -0
  46. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/conftest.py +0 -0
  47. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/README.md +0 -0
  48. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/artifacts2/TestCurrency.sol/TestCurrency.json +0 -0
  49. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/Count.sol +0 -0
  50. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/Counter.sol +0 -0
  51. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/CounterUpgradeable.sol +0 -0
  52. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/CounterUpgradeableWithLibrary.sol +0 -0
  53. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/CounterWithLibrary.sol +0 -0
  54. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/Datatypes.sol +0 -0
  55. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/EventLauncher.sol +0 -0
  56. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/TestCurrency.sol +0 -0
  57. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/TestCurrencyUUPS.sol +0 -0
  58. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/contracts/TestNFT.sol +0 -0
  59. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/hardhat.config.js +0 -0
  60. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/package-lock.json +0 -0
  61. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/package.json +0 -0
  62. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/verifiable-binaries/@anotherOrg/aPkg/1.0.2/build/contracts/TestCurrency.sol/TestCurrency.json +0 -0
  63. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/verifiable-binaries/@org/pkg/0.2.1/build/contracts/TestCurrency.json +0 -0
  64. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/hardhat-project/verifiable-binaries/@org/pkg/0.3.0/build/contracts/TestCurrency.json +0 -0
  65. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_aa_bundler.py +0 -0
  66. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_build_artifacts.py +0 -0
  67. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_contracts.py +0 -0
  68. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_defender.py +0 -0
  69. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_time_control.py +0 -0
  70. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_w3.py +0 -0
  71. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tests/test_wadray.py +0 -0
  72. {eth_prototype-1.5.1 → eth_prototype-1.5.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eth-prototype
3
- Version: 1.5.1
3
+ Version: 1.5.2
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eth-prototype
3
- Version: 1.5.1
3
+ Version: 1.5.2
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
@@ -3,7 +3,6 @@ from collections import defaultdict
3
3
  from dataclasses import dataclass, replace
4
4
  from enum import Enum
5
5
  from threading import local
6
- from warnings import warn
7
6
 
8
7
  from environs import Env
9
8
  from eth_abi import encode
@@ -48,7 +47,6 @@ NonceMode = Enum(
48
47
 
49
48
  AA_BUNDLER_NONCE_MODE = env.enum("AA_BUNDLER_NONCE_MODE", default="FIXED_KEY_LOCAL_NONCE", enum=NonceMode)
50
49
  AA_BUNDLER_NONCE_KEY = env.int("AA_BUNDLER_NONCE_KEY", 0)
51
- AA_BUNDLER_MAX_GETNONCE_RETRIES = env.int("AA_BUNDLER_MAX_GETNONCE_RETRIES", 3)
52
50
  AA_BUNDLER_ALCHEMY_GAS_POLICY_ID = env.str("AA_BUNDLER_ALCHEMY_GAS_POLICY_ID", None)
53
51
  AA_BUNDLER_USE_EXECUTE_USER_OP = env.bool("AA_BUNDLER_USE_EXECUTE_USER_OP", False)
54
52
 
@@ -88,6 +86,12 @@ class BundlerError(Exception):
88
86
  pass
89
87
 
90
88
 
89
+ class NonceError(BundlerRevertError):
90
+ """Raised when the bundler returns an AA25 invalid account nonce error."""
91
+
92
+ pass
93
+
94
+
91
95
  @dataclass(frozen=True)
92
96
  class UserOpEstimation:
93
97
  """eth_estimateUserOperationGas response"""
@@ -364,18 +368,9 @@ def consume_nonce(nonce_key, nonce):
364
368
  NONCE_CACHE[nonce_key] = max(NONCE_CACHE[nonce_key], nonce + 1)
365
369
 
366
370
 
367
- def check_nonce_error(resp, retry_nonce):
368
- """Returns the next nonce if resp contains a nonce error and retries weren't exhausted
369
- Raises RevertError otherwise
370
- """
371
- if "AA25" in resp["error"]["message"] and AA_BUNDLER_MAX_GETNONCE_RETRIES > 0:
372
- # Retry fetching the nonce
373
- if retry_nonce == AA_BUNDLER_MAX_GETNONCE_RETRIES:
374
- raise BundlerRevertError(resp["error"]["message"], response=resp)
375
- warn(f'{resp["error"]["message"]} error, I will retry fetching the nonce')
376
- return (retry_nonce or 0) + 1
377
- else:
378
- raise BundlerRevertError(resp["error"]["message"], response=resp)
371
+ def is_nonce_error(resp):
372
+ """Check if a bundler response contains an AA25 nonce error."""
373
+ return "error" in resp and "AA25" in resp["error"]["message"]
379
374
 
380
375
 
381
376
  def get_sender(tx):
@@ -579,19 +574,18 @@ class Bundler:
579
574
  total_fee = int(resp["result"]["standard"]["maxFeePerGas"], 16)
580
575
  base_fee = total_fee - priority_fee
581
576
  max_priority_fee_per_gas = int(priority_fee * self.priority_gas_price_factor)
582
- max_fee_per_gas = min(max_priority_fee_per_gas + base_fee, self.max_fee_per_gas)
577
+ max_fee_per_gas = max_priority_fee_per_gas + base_fee
583
578
  return GasPrice(max_priority_fee_per_gas=max_priority_fee_per_gas, max_fee_per_gas=max_fee_per_gas)
584
579
 
585
580
  def generic_gas_price(self):
586
581
  base_fee = self.get_base_fee()
587
582
  priority_fee = self.w3.eth.max_priority_fee
588
583
  max_priority_fee_per_gas = int(priority_fee * self.priority_gas_price_factor)
589
- max_fee_per_gas = min(max_priority_fee_per_gas + base_fee, self.max_fee_per_gas)
584
+ max_fee_per_gas = max_priority_fee_per_gas + base_fee
590
585
  return GasPrice(max_priority_fee_per_gas=max_priority_fee_per_gas, max_fee_per_gas=max_fee_per_gas)
591
586
 
592
- def build_user_operation(self, tx: Tx, retry_nonce=None) -> UserOperation:
593
- nonce_key, nonce = self.get_nonce_and_key(tx, fetch=retry_nonce is not None)
594
- # Consume the nonce, even if the userop may fail later
587
+ def build_user_operation(self, tx: Tx, enable_cap=True) -> UserOperation:
588
+ nonce_key, nonce = self.get_nonce_and_key(tx)
595
589
  consume_nonce(nonce_key, nonce)
596
590
 
597
591
  user_operation = UserOperation.from_tx(
@@ -613,7 +607,11 @@ class Bundler:
613
607
  user_operation = user_operation.add_estimation(estimation)
614
608
 
615
609
  gas_price = self.pimlico_gas_price()
616
-
610
+ if enable_cap:
611
+ gas_price = GasPrice(
612
+ max_priority_fee_per_gas=gas_price.max_priority_fee_per_gas,
613
+ max_fee_per_gas=min(gas_price.max_fee_per_gas, self.max_fee_per_gas),
614
+ )
617
615
  user_operation = user_operation.add_gas_price(gas_price)
618
616
 
619
617
  elif self.bundler_type == "generic":
@@ -622,7 +620,11 @@ class Bundler:
622
620
  user_operation = user_operation.add_estimation(estimation)
623
621
 
624
622
  gas_price = self.generic_gas_price()
625
-
623
+ if enable_cap:
624
+ gas_price = GasPrice(
625
+ max_priority_fee_per_gas=gas_price.max_priority_fee_per_gas,
626
+ max_fee_per_gas=min(gas_price.max_fee_per_gas, self.max_fee_per_gas),
627
+ )
626
628
  user_operation = user_operation.add_gas_price(gas_price)
627
629
 
628
630
  else:
@@ -630,25 +632,18 @@ class Bundler:
630
632
 
631
633
  return user_operation
632
634
 
633
- def send_transaction(self, tx: Tx, retry_nonce=None):
634
- user_operation = self.build_user_operation(tx, retry_nonce).sign(
635
- self.account.key, tx.chain_id, self.entrypoint
636
- )
635
+ def send_transaction(self, tx: Tx):
636
+ user_operation = self.build_user_operation(tx).sign(self.account.key, tx.chain_id, self.entrypoint)
637
+ return self.send_user_operation(user_operation)
637
638
 
639
+ def send_user_operation(self, user_operation: UserOperation):
638
640
  resp = self.bundler.provider.make_request(
639
641
  "eth_sendUserOperation", [user_operation.as_dict(), self.entrypoint]
640
642
  )
641
643
  if "error" in resp:
642
- try:
643
- next_nonce = check_nonce_error(resp, retry_nonce)
644
- except BundlerRevertError as e:
645
- raise BundlerRevertError(
646
- e.message,
647
- userop=user_operation,
648
- response=e.response,
649
- )
650
- return self.send_transaction(tx, retry_nonce=next_nonce)
651
-
644
+ if is_nonce_error(resp):
645
+ raise NonceError(resp["error"]["message"], userop=user_operation, response=resp)
646
+ raise BundlerRevertError(resp["error"]["message"], userop=user_operation, response=resp)
652
647
  return {"userOpHash": resp["result"]}
653
648
 
654
649
  def get_user_operation(self, user_op_hash):
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