eth-prototype 1.3.1__py3-none-any.whl → 1.3.3__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.
- {eth_prototype-1.3.1.dist-info → eth_prototype-1.3.3.dist-info}/METADATA +1 -1
- {eth_prototype-1.3.1.dist-info → eth_prototype-1.3.3.dist-info}/RECORD +7 -7
- {eth_prototype-1.3.1.dist-info → eth_prototype-1.3.3.dist-info}/WHEEL +1 -1
- ethproto/aa_bundler.py +47 -13
- {eth_prototype-1.3.1.dist-info → eth_prototype-1.3.3.dist-info}/licenses/AUTHORS.rst +0 -0
- {eth_prototype-1.3.1.dist-info → eth_prototype-1.3.3.dist-info}/licenses/LICENSE.txt +0 -0
- {eth_prototype-1.3.1.dist-info → eth_prototype-1.3.3.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
|
|
1
|
-
eth_prototype-1.3.
|
2
|
-
eth_prototype-1.3.
|
1
|
+
eth_prototype-1.3.3.dist-info/licenses/AUTHORS.rst,sha256=Ui-05yYXtDZxna6o1yNcfdm8Jt68UIDQ01osiLxlYlU,95
|
2
|
+
eth_prototype-1.3.3.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=
|
4
|
+
ethproto/aa_bundler.py,sha256=W47fIA_w7orUu7yczfHPaHpUJRFh5op0YZHPgW3Iwik,17420
|
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.
|
16
|
-
eth_prototype-1.3.
|
17
|
-
eth_prototype-1.3.
|
18
|
-
eth_prototype-1.3.
|
15
|
+
eth_prototype-1.3.3.dist-info/METADATA,sha256=79aBgMQ-TmEM3SO0Lhl9lG9mJeD8PEsqRD4me1VSqhQ,2650
|
16
|
+
eth_prototype-1.3.3.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
17
|
+
eth_prototype-1.3.3.dist-info/top_level.txt,sha256=Dl0X7m6N1hxeo4JpGpSNqWC2gtsN0731g-DL1J0mpjc,9
|
18
|
+
eth_prototype-1.3.3.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
|
|
@@ -29,6 +29,9 @@ AA_BUNDLER_GAS_LIMIT_FACTOR = env.float("AA_BUNDLER_GAS_LIMIT_FACTOR", 1)
|
|
29
29
|
AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR", 1)
|
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
|
+
AA_BUNDLER_MAX_FEE_PER_GAS = env.int("AA_BUNDLER_MAX_FEE_PER_GAS", 200000000000) # 200 gwei
|
33
|
+
|
34
|
+
AA_BUNDLER_STATE_OVERRIDES = env.json("AA_BUNDLER_STATE_OVERRIDES", default={})
|
32
35
|
|
33
36
|
NonceMode = Enum(
|
34
37
|
"NonceMode",
|
@@ -68,6 +71,16 @@ DUMMY_SIGNATURE = HexBytes(
|
|
68
71
|
)
|
69
72
|
|
70
73
|
|
74
|
+
class BundlerRevertError(RevertError):
|
75
|
+
"""Bundler specific revert error"""
|
76
|
+
|
77
|
+
def __init__(self, message, userop=None, response=None):
|
78
|
+
super().__init__(message)
|
79
|
+
self.message = message
|
80
|
+
self.userop = userop
|
81
|
+
self.response = response
|
82
|
+
|
83
|
+
|
71
84
|
@dataclass(frozen=True)
|
72
85
|
class UserOpEstimation:
|
73
86
|
"""eth_estimateUserOperationGas response"""
|
@@ -288,11 +301,11 @@ def check_nonce_error(resp, retry_nonce):
|
|
288
301
|
if "AA25" in resp["error"]["message"] and AA_BUNDLER_MAX_GETNONCE_RETRIES > 0:
|
289
302
|
# Retry fetching the nonce
|
290
303
|
if retry_nonce == AA_BUNDLER_MAX_GETNONCE_RETRIES:
|
291
|
-
raise
|
304
|
+
raise BundlerRevertError(resp["error"]["message"], response=resp)
|
292
305
|
warn(f'{resp["error"]["message"]} error, I will retry fetching the nonce')
|
293
306
|
return (retry_nonce or 0) + 1
|
294
307
|
else:
|
295
|
-
raise
|
308
|
+
raise BundlerRevertError(resp["error"]["message"], response=resp)
|
296
309
|
|
297
310
|
|
298
311
|
def get_sender(tx):
|
@@ -317,7 +330,9 @@ class Bundler:
|
|
317
330
|
gas_limit_factor: float = AA_BUNDLER_GAS_LIMIT_FACTOR,
|
318
331
|
priority_gas_price_factor: float = AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR,
|
319
332
|
base_gas_price_factor: float = AA_BUNDLER_BASE_GAS_PRICE_FACTOR,
|
333
|
+
max_fee_per_gas: int = AA_BUNDLER_MAX_FEE_PER_GAS,
|
320
334
|
executor_pk: HexBytes = AA_BUNDLER_EXECUTOR_PK,
|
335
|
+
overrides: StateOverride = AA_BUNDLER_STATE_OVERRIDES,
|
321
336
|
):
|
322
337
|
self.w3 = w3
|
323
338
|
self.bundler = Web3(Web3.HTTPProvider(bundler_url), middleware=[])
|
@@ -330,13 +345,18 @@ class Bundler:
|
|
330
345
|
self.priority_gas_price_factor = priority_gas_price_factor
|
331
346
|
self.base_gas_price_factor = base_gas_price_factor
|
332
347
|
self.executor_pk = executor_pk
|
348
|
+
self.max_fee_per_gas = max_fee_per_gas
|
349
|
+
|
350
|
+
# stateOverrideSet mapping to use when calling eth_estimateUserOperationGas
|
351
|
+
# https://docs.alchemy.com/reference/eth-estimateuseroperationgas
|
352
|
+
self.overrides = overrides
|
333
353
|
|
334
354
|
def __str__(self):
|
335
355
|
return (
|
336
356
|
f"Bundler(type={self.bundler_type}, entrypoint={self.entrypoint}, nonce_mode={self.nonce_mode}, "
|
337
357
|
f"fixed_nonce_key={self.fixed_nonce_key}, verification_gas_factor={self.verification_gas_factor}, "
|
338
358
|
f"gas_limit_factor={self.gas_limit_factor}, priority_gas_price_factor={self.priority_gas_price_factor}, "
|
339
|
-
f"base_gas_price_factor={self.base_gas_price_factor})"
|
359
|
+
f"base_gas_price_factor={self.base_gas_price_factor}, max_fee_per_gas={self.max_fee_per_gas})"
|
340
360
|
)
|
341
361
|
|
342
362
|
def get_nonce_and_key(self, tx: Tx, fetch=False):
|
@@ -364,10 +384,11 @@ class Bundler:
|
|
364
384
|
|
365
385
|
def estimate_user_operation_gas(self, user_operation: UserOperation) -> UserOpEstimation:
|
366
386
|
resp = self.bundler.provider.make_request(
|
367
|
-
"eth_estimateUserOperationGas",
|
387
|
+
"eth_estimateUserOperationGas",
|
388
|
+
[user_operation.as_reduced_dict(), self.entrypoint, self.overrides],
|
368
389
|
)
|
369
390
|
if "error" in resp:
|
370
|
-
raise
|
391
|
+
raise BundlerRevertError(resp["error"]["message"], user_operation, resp)
|
371
392
|
|
372
393
|
paymaster_verification_gas_limit = resp["result"].get("paymasterVerificationGasLimit", "0x00")
|
373
394
|
return UserOpEstimation(
|
@@ -386,10 +407,17 @@ class Bundler:
|
|
386
407
|
def alchemy_gas_price(self):
|
387
408
|
resp = self.bundler.provider.make_request("rundler_maxPriorityFeePerGas", [])
|
388
409
|
if "error" in resp:
|
389
|
-
raise
|
410
|
+
raise BundlerRevertError(resp["error"]["message"], response=resp)
|
390
411
|
max_priority_fee_per_gas = int(int(resp["result"], 16) * self.priority_gas_price_factor)
|
391
|
-
max_fee_per_gas = max_priority_fee_per_gas + self.get_base_fee()
|
412
|
+
max_fee_per_gas = min(max_priority_fee_per_gas + self.get_base_fee(), self.max_fee_per_gas)
|
413
|
+
|
414
|
+
return GasPrice(max_priority_fee_per_gas=max_priority_fee_per_gas, max_fee_per_gas=max_fee_per_gas)
|
392
415
|
|
416
|
+
def generic_gas_price(self):
|
417
|
+
base_fee = self.get_base_fee()
|
418
|
+
priority_fee = self.w3.eth.max_priority_fee
|
419
|
+
max_priority_fee_per_gas = int(priority_fee * self.priority_gas_price_factor)
|
420
|
+
max_fee_per_gas = min(max_priority_fee_per_gas + base_fee, self.max_fee_per_gas)
|
393
421
|
return GasPrice(max_priority_fee_per_gas=max_priority_fee_per_gas, max_fee_per_gas=max_fee_per_gas)
|
394
422
|
|
395
423
|
def build_user_operation(self, tx: Tx, retry_nonce=None) -> UserOperation:
|
@@ -404,16 +432,15 @@ class Bundler:
|
|
404
432
|
|
405
433
|
if self.bundler_type == "alchemy":
|
406
434
|
gas_price = self.alchemy_gas_price()
|
407
|
-
user_operation = user_operation.add_gas_price(gas_price)
|
408
435
|
|
409
436
|
elif self.bundler_type == "generic":
|
410
|
-
|
411
|
-
pass
|
437
|
+
gas_price = self.generic_gas_price()
|
412
438
|
|
413
439
|
else:
|
414
440
|
warn(f"Unknown bundler_type: {self.bundler_type}")
|
441
|
+
gas_price = GasPrice(0, 0)
|
415
442
|
|
416
|
-
return user_operation
|
443
|
+
return user_operation.add_gas_price(gas_price)
|
417
444
|
|
418
445
|
def send_transaction(self, tx: Tx, retry_nonce=None):
|
419
446
|
user_operation = self.build_user_operation(tx, retry_nonce).sign(
|
@@ -424,7 +451,14 @@ class Bundler:
|
|
424
451
|
"eth_sendUserOperation", [user_operation.as_dict(), self.entrypoint]
|
425
452
|
)
|
426
453
|
if "error" in resp:
|
427
|
-
|
454
|
+
try:
|
455
|
+
next_nonce = check_nonce_error(resp, retry_nonce)
|
456
|
+
except BundlerRevertError as e:
|
457
|
+
raise BundlerRevertError(
|
458
|
+
e.message,
|
459
|
+
userop=user_operation,
|
460
|
+
response=e.response,
|
461
|
+
)
|
428
462
|
return self.send_transaction(tx, retry_nonce=next_nonce)
|
429
463
|
|
430
464
|
return {"userOpHash": resp["result"]}
|
File without changes
|
File without changes
|
File without changes
|