eth-prototype 1.3.1__py3-none-any.whl → 1.3.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eth-prototype
3
- Version: 1.3.1
3
+ Version: 1.3.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,7 +1,7 @@
1
- eth_prototype-1.3.1.dist-info/licenses/AUTHORS.rst,sha256=Ui-05yYXtDZxna6o1yNcfdm8Jt68UIDQ01osiLxlYlU,95
2
- eth_prototype-1.3.1.dist-info/licenses/LICENSE.txt,sha256=U_Q6_nDYDwZPIuhttHi37hXZ2qU2-HlV2geo9hzHXFw,1087
1
+ eth_prototype-1.3.2.dist-info/licenses/AUTHORS.rst,sha256=Ui-05yYXtDZxna6o1yNcfdm8Jt68UIDQ01osiLxlYlU,95
2
+ eth_prototype-1.3.2.dist-info/licenses/LICENSE.txt,sha256=U_Q6_nDYDwZPIuhttHi37hXZ2qU2-HlV2geo9hzHXFw,1087
3
3
  ethproto/__init__.py,sha256=YWkAFysBp4tZjLWWB2FFmp5yG23pUYhQvgQW9b3soXs,579
4
- ethproto/aa_bundler.py,sha256=hwUWkd-9upeUb0_ZJ2mPs8mAt-lmp-2F6xkO8GA1fTw,15793
4
+ ethproto/aa_bundler.py,sha256=yl-kgLtjIi4ratPquD0B71QtA29SNAwOiIOXNLvxCOk,16780
5
5
  ethproto/build_artifacts.py,sha256=whIXEqnh5f89UYu4Cb3KDigGV7juUCbDnfZkg-SYMKA,9878
6
6
  ethproto/contracts.py,sha256=rNVbCK1hURy7lWKhzSdXgVWo3wx9O_Ghk-6PfgOsRNk,18662
7
7
  ethproto/defender_relay.py,sha256=05A8TfRZwiBhCpo924Pf9CjfKSir2Wvgg1p_asFxJbw,1777
@@ -12,7 +12,7 @@ ethproto/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
12
12
  ethproto/test_utils/factories.py,sha256=G8DnUDG_yThRxMTCkymzcjm9lR_ni0_ZmTsb3sEfIdI,1805
13
13
  ethproto/test_utils/hardhat.py,sha256=HzTqIznu6zVd_-doL96ftFJ235ktDCQen1QDQbNuwfM,2361
14
14
  ethproto/test_utils/vcr_utils.py,sha256=1FH2sgJlElSjWkJLuO3C7E2J-4HKyFvjAqkCnGRZJyk,797
15
- eth_prototype-1.3.1.dist-info/METADATA,sha256=BjVmjZbubsPyMmDHyDtIqgYc5-T4uS1Xzd_lrMd2gZA,2650
16
- eth_prototype-1.3.1.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
17
- eth_prototype-1.3.1.dist-info/top_level.txt,sha256=Dl0X7m6N1hxeo4JpGpSNqWC2gtsN0731g-DL1J0mpjc,9
18
- eth_prototype-1.3.1.dist-info/RECORD,,
15
+ eth_prototype-1.3.2.dist-info/METADATA,sha256=vkIpd-qbMF_GtzUe4TW2_rwV9ypTQqxDW3V9uDhtIR8,2650
16
+ eth_prototype-1.3.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
17
+ eth_prototype-1.3.2.dist-info/top_level.txt,sha256=Dl0X7m6N1hxeo4JpGpSNqWC2gtsN0731g-DL1J0mpjc,9
18
+ eth_prototype-1.3.2.dist-info/RECORD,,
ethproto/aa_bundler.py CHANGED
@@ -14,7 +14,7 @@ from eth_utils import add_0x_prefix, function_signature_to_4byte_selector
14
14
  from hexbytes import HexBytes
15
15
  from web3 import Web3
16
16
  from web3.constants import ADDRESS_ZERO
17
- from web3.types import TxParams
17
+ from web3.types import StateOverride, TxParams
18
18
 
19
19
  from .contracts import RevertError
20
20
 
@@ -30,6 +30,8 @@ AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_PRIORITY_GAS_PRICE_
30
30
  AA_BUNDLER_BASE_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_BASE_GAS_PRICE_FACTOR", 1)
31
31
  AA_BUNDLER_VERIFICATION_GAS_FACTOR = env.float("AA_BUNDLER_VERIFICATION_GAS_FACTOR", 1)
32
32
 
33
+ AA_BUNDLER_STATE_OVERRIDES = env.json("AA_BUNDLER_STATE_OVERRIDES", default={})
34
+
33
35
  NonceMode = Enum(
34
36
  "NonceMode",
35
37
  [
@@ -68,6 +70,16 @@ DUMMY_SIGNATURE = HexBytes(
68
70
  )
69
71
 
70
72
 
73
+ class BundlerRevertError(RevertError):
74
+ """Bundler specific revert error"""
75
+
76
+ def __init__(self, message, userop=None, response=None):
77
+ super().__init__(message)
78
+ self.message = message
79
+ self.userop = userop
80
+ self.response = response
81
+
82
+
71
83
  @dataclass(frozen=True)
72
84
  class UserOpEstimation:
73
85
  """eth_estimateUserOperationGas response"""
@@ -288,11 +300,11 @@ def check_nonce_error(resp, retry_nonce):
288
300
  if "AA25" in resp["error"]["message"] and AA_BUNDLER_MAX_GETNONCE_RETRIES > 0:
289
301
  # Retry fetching the nonce
290
302
  if retry_nonce == AA_BUNDLER_MAX_GETNONCE_RETRIES:
291
- raise RevertError(resp["error"]["message"])
303
+ raise BundlerRevertError(resp["error"]["message"], response=resp)
292
304
  warn(f'{resp["error"]["message"]} error, I will retry fetching the nonce')
293
305
  return (retry_nonce or 0) + 1
294
306
  else:
295
- raise RevertError(resp["error"]["message"])
307
+ raise BundlerRevertError(resp["error"]["message"], response=resp)
296
308
 
297
309
 
298
310
  def get_sender(tx):
@@ -318,6 +330,7 @@ class Bundler:
318
330
  priority_gas_price_factor: float = AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR,
319
331
  base_gas_price_factor: float = AA_BUNDLER_BASE_GAS_PRICE_FACTOR,
320
332
  executor_pk: HexBytes = AA_BUNDLER_EXECUTOR_PK,
333
+ overrides: StateOverride = AA_BUNDLER_STATE_OVERRIDES,
321
334
  ):
322
335
  self.w3 = w3
323
336
  self.bundler = Web3(Web3.HTTPProvider(bundler_url), middleware=[])
@@ -331,6 +344,10 @@ class Bundler:
331
344
  self.base_gas_price_factor = base_gas_price_factor
332
345
  self.executor_pk = executor_pk
333
346
 
347
+ # stateOverrideSet mapping to use when calling eth_estimateUserOperationGas
348
+ # https://docs.alchemy.com/reference/eth-estimateuseroperationgas
349
+ self.overrides = overrides
350
+
334
351
  def __str__(self):
335
352
  return (
336
353
  f"Bundler(type={self.bundler_type}, entrypoint={self.entrypoint}, nonce_mode={self.nonce_mode}, "
@@ -364,10 +381,11 @@ class Bundler:
364
381
 
365
382
  def estimate_user_operation_gas(self, user_operation: UserOperation) -> UserOpEstimation:
366
383
  resp = self.bundler.provider.make_request(
367
- "eth_estimateUserOperationGas", [user_operation.as_reduced_dict(), self.entrypoint]
384
+ "eth_estimateUserOperationGas",
385
+ [user_operation.as_reduced_dict(), self.entrypoint, self.overrides],
368
386
  )
369
387
  if "error" in resp:
370
- raise RevertError(resp["error"]["message"])
388
+ raise BundlerRevertError(resp["error"]["message"], user_operation, resp)
371
389
 
372
390
  paymaster_verification_gas_limit = resp["result"].get("paymasterVerificationGasLimit", "0x00")
373
391
  return UserOpEstimation(
@@ -386,7 +404,7 @@ class Bundler:
386
404
  def alchemy_gas_price(self):
387
405
  resp = self.bundler.provider.make_request("rundler_maxPriorityFeePerGas", [])
388
406
  if "error" in resp:
389
- raise RevertError(resp["error"]["message"])
407
+ raise BundlerRevertError(resp["error"]["message"], response=resp)
390
408
  max_priority_fee_per_gas = int(int(resp["result"], 16) * self.priority_gas_price_factor)
391
409
  max_fee_per_gas = max_priority_fee_per_gas + self.get_base_fee()
392
410
 
@@ -424,7 +442,14 @@ class Bundler:
424
442
  "eth_sendUserOperation", [user_operation.as_dict(), self.entrypoint]
425
443
  )
426
444
  if "error" in resp:
427
- next_nonce = check_nonce_error(resp, retry_nonce)
445
+ try:
446
+ next_nonce = check_nonce_error(resp, retry_nonce)
447
+ except BundlerRevertError as e:
448
+ raise BundlerRevertError(
449
+ e.message,
450
+ userop=user_operation,
451
+ response=e.response,
452
+ )
428
453
  return self.send_transaction(tx, retry_nonce=next_nonce)
429
454
 
430
455
  return {"userOpHash": resp["result"]}