eth-prototype 1.1.1__py3-none-any.whl → 1.1.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.
- {eth_prototype-1.1.1.dist-info → eth_prototype-1.1.2.dist-info}/METADATA +1 -1
- eth_prototype-1.1.2.dist-info/RECORD +14 -0
- {eth_prototype-1.1.1.dist-info → eth_prototype-1.1.2.dist-info}/WHEEL +1 -1
- ethproto/aa_bundler.py +67 -35
- ethproto/w3wrappers.py +4 -4
- eth_prototype-1.1.1.dist-info/RECORD +0 -14
- {eth_prototype-1.1.1.dist-info → eth_prototype-1.1.2.dist-info}/AUTHORS.rst +0 -0
- {eth_prototype-1.1.1.dist-info → eth_prototype-1.1.2.dist-info}/LICENSE.txt +0 -0
- {eth_prototype-1.1.1.dist-info → eth_prototype-1.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,14 @@
|
|
1
|
+
ethproto/__init__.py,sha256=YWkAFysBp4tZjLWWB2FFmp5yG23pUYhQvgQW9b3soXs,579
|
2
|
+
ethproto/aa_bundler.py,sha256=wWUa-uqTvDKUI7ewxfCQzUsVxIPhu7N-kSHu-_aXtJ4,10495
|
3
|
+
ethproto/build_artifacts.py,sha256=xwCd5hJUHP82IA-y3sSfX6fV15kjCGtV19RxNRcoor0,5441
|
4
|
+
ethproto/contracts.py,sha256=rNVbCK1hURy7lWKhzSdXgVWo3wx9O_Ghk-6PfgOsRNk,18662
|
5
|
+
ethproto/defender_relay.py,sha256=05A8TfRZwiBhCpo924Pf9CjfKSir2Wvgg1p_asFxJbw,1777
|
6
|
+
ethproto/w3wrappers.py,sha256=0lm-h-3QpoKK54HvQ66hm_fbaVRy6QFuzedTks3FeFA,21245
|
7
|
+
ethproto/wadray.py,sha256=JBsu5KcyU9k70bDK03T2IY6qPVFO30WbYPhwrAHdXao,8262
|
8
|
+
ethproto/wrappers.py,sha256=9qDwRDOXw3wquzvGfIsub-VPWm98GBWP7dHLFOUPWzg,17307
|
9
|
+
eth_prototype-1.1.2.dist-info/AUTHORS.rst,sha256=Ui-05yYXtDZxna6o1yNcfdm8Jt68UIDQ01osiLxlYlU,95
|
10
|
+
eth_prototype-1.1.2.dist-info/LICENSE.txt,sha256=U_Q6_nDYDwZPIuhttHi37hXZ2qU2-HlV2geo9hzHXFw,1087
|
11
|
+
eth_prototype-1.1.2.dist-info/METADATA,sha256=Iao560GckmPsEsXAtt1Cm8wEZwElZvzucStqIiTGP9k,2482
|
12
|
+
eth_prototype-1.1.2.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
13
|
+
eth_prototype-1.1.2.dist-info/top_level.txt,sha256=Dl0X7m6N1hxeo4JpGpSNqWC2gtsN0731g-DL1J0mpjc,9
|
14
|
+
eth_prototype-1.1.2.dist-info/RECORD,,
|
ethproto/aa_bundler.py
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
import random
|
2
|
-
from
|
2
|
+
from collections import defaultdict
|
3
3
|
from enum import Enum
|
4
|
-
import
|
4
|
+
from threading import local
|
5
|
+
from warnings import warn
|
6
|
+
|
5
7
|
from environs import Env
|
6
8
|
from eth_abi import encode
|
7
9
|
from eth_account import Account
|
@@ -9,8 +11,8 @@ from eth_account.messages import encode_defunct
|
|
9
11
|
from hexbytes import HexBytes
|
10
12
|
from web3 import Web3
|
11
13
|
from web3.constants import ADDRESS_ZERO
|
12
|
-
from .contracts import RevertError
|
13
14
|
|
15
|
+
from .contracts import RevertError
|
14
16
|
|
15
17
|
env = Env()
|
16
18
|
|
@@ -21,6 +23,7 @@ AA_BUNDLER_PROVIDER = env.str("AA_BUNDLER_PROVIDER", "alchemy")
|
|
21
23
|
AA_BUNDLER_GAS_LIMIT_FACTOR = env.float("AA_BUNDLER_GAS_LIMIT_FACTOR", 1)
|
22
24
|
AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR", 1)
|
23
25
|
AA_BUNDLER_BASE_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_BASE_GAS_PRICE_FACTOR", 1)
|
26
|
+
AA_BUNDLER_VERIFICATION_GAS_FACTOR = env.float("AA_BUNDLER_VERIFICATION_GAS_FACTOR", 1)
|
24
27
|
|
25
28
|
NonceMode = Enum(
|
26
29
|
"NonceMode",
|
@@ -50,8 +53,8 @@ GET_NONCE_ABI = [
|
|
50
53
|
}
|
51
54
|
]
|
52
55
|
|
53
|
-
NONCE_CACHE =
|
54
|
-
RANDOM_NONCE_KEY =
|
56
|
+
NONCE_CACHE = defaultdict(lambda: 0)
|
57
|
+
RANDOM_NONCE_KEY = local()
|
55
58
|
|
56
59
|
|
57
60
|
def pack_two(a, b):
|
@@ -68,6 +71,10 @@ def _to_uint(x):
|
|
68
71
|
raise RuntimeError(f"Invalid int value {x}")
|
69
72
|
|
70
73
|
|
74
|
+
def apply_factor(x, factor):
|
75
|
+
return int(_to_uint(x) * factor)
|
76
|
+
|
77
|
+
|
71
78
|
def pack_user_operation(user_operation):
|
72
79
|
# https://github.com/eth-infinitism/account-abstraction/blob/develop/contracts/interfaces/PackedUserOperation.sol
|
73
80
|
return {
|
@@ -133,10 +140,9 @@ def fetch_nonce(w3, account, entry_point, nonce_key):
|
|
133
140
|
|
134
141
|
|
135
142
|
def get_random_nonce_key():
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
return RANDOM_NONCE_KEY
|
143
|
+
if getattr(RANDOM_NONCE_KEY, "key", None) is None:
|
144
|
+
RANDOM_NONCE_KEY.key = random.randint(1, 2**192 - 1)
|
145
|
+
return RANDOM_NONCE_KEY.key
|
140
146
|
|
141
147
|
|
142
148
|
def get_nonce_and_key(w3, tx, nonce_mode, entry_point=AA_BUNDLER_ENTRYPOINT, fetch=False):
|
@@ -152,20 +158,25 @@ def get_nonce_and_key(w3, tx, nonce_mode, entry_point=AA_BUNDLER_ENTRYPOINT, fet
|
|
152
158
|
if nonce is None:
|
153
159
|
if fetch or nonce_mode == NonceMode.FIXED_KEY_FETCH_ALWAYS:
|
154
160
|
nonce = fetch_nonce(w3, get_sender(tx), entry_point, nonce_key)
|
155
|
-
elif nonce_key not in NONCE_CACHE:
|
156
|
-
nonce = 0
|
157
161
|
else:
|
158
162
|
nonce = NONCE_CACHE[nonce_key]
|
159
163
|
return nonce_key, nonce
|
160
164
|
|
161
165
|
|
162
|
-
def
|
166
|
+
def consume_nonce(nonce_key, nonce):
|
167
|
+
NONCE_CACHE[nonce_key] = max(NONCE_CACHE[nonce_key], nonce + 1)
|
168
|
+
|
169
|
+
|
170
|
+
def check_nonce_error(resp, retry_nonce):
|
171
|
+
"""Returns the next nonce if resp contains a nonce error and retries weren't exhausted
|
172
|
+
Raises RevertError otherwise
|
173
|
+
"""
|
163
174
|
if "AA25" in resp["error"]["message"] and AA_BUNDLER_MAX_GETNONCE_RETRIES > 0:
|
164
175
|
# Retry fetching the nonce
|
165
176
|
if retry_nonce == AA_BUNDLER_MAX_GETNONCE_RETRIES:
|
166
177
|
raise RevertError(resp["error"]["message"])
|
167
178
|
warn(f'{resp["error"]["message"]} error, I will retry fetching the nonce')
|
168
|
-
return
|
179
|
+
return (retry_nonce or 0) + 1
|
169
180
|
else:
|
170
181
|
raise RevertError(resp["error"]["message"])
|
171
182
|
|
@@ -184,7 +195,7 @@ def get_sender(tx):
|
|
184
195
|
return tx["from"]
|
185
196
|
|
186
197
|
|
187
|
-
def
|
198
|
+
def build_user_operation(w3, tx, retry_nonce=None):
|
188
199
|
nonce_key, nonce = get_nonce_and_key(
|
189
200
|
w3, tx, AA_BUNDLER_NONCE_MODE, entry_point=AA_BUNDLER_ENTRYPOINT, fetch=retry_nonce is not None
|
190
201
|
)
|
@@ -209,42 +220,63 @@ def send_transaction(w3, tx, retry_nonce=None):
|
|
209
220
|
"eth_estimateUserOperationGas", [user_operation, AA_BUNDLER_ENTRYPOINT]
|
210
221
|
)
|
211
222
|
if "error" in resp:
|
212
|
-
|
223
|
+
next_nonce = check_nonce_error(resp, retry_nonce)
|
224
|
+
return build_user_operation(w3, tx, retry_nonce=next_nonce)
|
213
225
|
|
214
226
|
user_operation.update(resp["result"])
|
215
227
|
|
216
228
|
resp = w3.provider.make_request("rundler_maxPriorityFeePerGas", [])
|
217
229
|
if "error" in resp:
|
218
230
|
raise RevertError(resp["error"]["message"])
|
219
|
-
|
220
|
-
user_operation["
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
elif AA_BUNDLER_PROVIDER == "gelato":
|
226
|
-
user_operation.update(
|
227
|
-
{
|
228
|
-
"preVerificationGas": "0x00",
|
229
|
-
"callGasLimit": "0x00",
|
230
|
-
"verificationGasLimit": "0x00",
|
231
|
-
"maxFeePerGas": "0x00",
|
232
|
-
"maxPriorityFeePerGas": "0x00",
|
233
|
-
}
|
231
|
+
user_operation["maxPriorityFeePerGas"] = resp["result"]
|
232
|
+
user_operation["maxFeePerGas"] = hex(int(resp["result"], 16) + get_base_fee(w3))
|
233
|
+
|
234
|
+
elif AA_BUNDLER_PROVIDER == "generic":
|
235
|
+
resp = w3.provider.make_request(
|
236
|
+
"eth_estimateUserOperationGas", [user_operation, AA_BUNDLER_ENTRYPOINT]
|
234
237
|
)
|
235
|
-
|
236
|
-
|
238
|
+
if "error" in resp:
|
239
|
+
next_nonce = check_nonce_error(resp, retry_nonce)
|
240
|
+
return build_user_operation(w3, tx, retry_nonce=next_nonce)
|
241
|
+
|
242
|
+
user_operation.update(resp["result"])
|
243
|
+
|
244
|
+
else:
|
245
|
+
warn(f"Unknown AA_BUNDLER_PROVIDER: {AA_BUNDLER_PROVIDER}")
|
246
|
+
|
247
|
+
# Apply increase factors
|
248
|
+
user_operation["verificationGasLimit"] = hex(
|
249
|
+
apply_factor(user_operation["verificationGasLimit"], AA_BUNDLER_VERIFICATION_GAS_FACTOR)
|
237
250
|
)
|
251
|
+
if "maxPriorityFeePerGas" in user_operation:
|
252
|
+
user_operation["maxPriorityFeePerGas"] = hex(
|
253
|
+
apply_factor(user_operation["maxPriorityFeePerGas"], AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR)
|
254
|
+
)
|
255
|
+
if "callGasLimit" in user_operation:
|
256
|
+
user_operation["callGasLimit"] = hex(
|
257
|
+
apply_factor(user_operation["callGasLimit"], AA_BUNDLER_GAS_LIMIT_FACTOR)
|
258
|
+
)
|
259
|
+
|
238
260
|
# Remove paymaster related fields
|
239
261
|
user_operation.pop("paymaster", None)
|
240
262
|
user_operation.pop("paymasterData", None)
|
241
263
|
user_operation.pop("paymasterVerificationGasLimit", None)
|
242
264
|
user_operation.pop("paymasterPostOpGasLimit", None)
|
243
265
|
|
266
|
+
# Consume the nonce, even if the userop may fail later
|
267
|
+
consume_nonce(nonce_key, nonce)
|
268
|
+
|
269
|
+
return user_operation
|
270
|
+
|
271
|
+
|
272
|
+
def send_transaction(w3, tx, retry_nonce=None):
|
273
|
+
user_operation = build_user_operation(w3, tx, retry_nonce)
|
274
|
+
user_operation["signature"] = sign_user_operation(
|
275
|
+
AA_BUNDLER_EXECUTOR_PK, user_operation, tx["chainId"], AA_BUNDLER_ENTRYPOINT
|
276
|
+
)
|
244
277
|
resp = w3.provider.make_request("eth_sendUserOperation", [user_operation, AA_BUNDLER_ENTRYPOINT])
|
245
278
|
if "error" in resp:
|
246
|
-
|
279
|
+
next_nonce = check_nonce_error(resp, retry_nonce)
|
280
|
+
return send_transaction(w3, tx, retry_nonce=next_nonce)
|
247
281
|
|
248
|
-
# Store nonce in the cache, so next time uses a new nonce
|
249
|
-
NONCE_CACHE[nonce_key] = nonce + 1
|
250
282
|
return {"userOpHash": resp["result"]}
|
ethproto/w3wrappers.py
CHANGED
@@ -444,7 +444,7 @@ class W3Provider(BaseProvider):
|
|
444
444
|
def get_events(self, eth_wrapper, event_name, filter_kwargs={}):
|
445
445
|
"""Returns a list of events given a filter, like this:
|
446
446
|
|
447
|
-
>>> provider.get_events(currencywrapper, "Transfer", dict(
|
447
|
+
>>> provider.get_events(currencywrapper, "Transfer", dict(from_block=0))
|
448
448
|
[AttributeDict({
|
449
449
|
'args': AttributeDict(
|
450
450
|
{'from': '0x0000000000000000000000000000000000000000',
|
@@ -463,8 +463,8 @@ class W3Provider(BaseProvider):
|
|
463
463
|
"""
|
464
464
|
contract = eth_wrapper.contract
|
465
465
|
event = getattr(contract.events, event_name)
|
466
|
-
if "
|
467
|
-
filter_kwargs["
|
466
|
+
if "from_block" not in filter_kwargs:
|
467
|
+
filter_kwargs["from_block"] = self.get_first_block(eth_wrapper)
|
468
468
|
event_filter = event.create_filter(**filter_kwargs)
|
469
469
|
return event_filter.get_all_entries()
|
470
470
|
|
@@ -490,7 +490,7 @@ class W3Provider(BaseProvider):
|
|
490
490
|
constructor_params, init_params = init_params
|
491
491
|
real_contract = self.construct(eth_contract, constructor_params, {"from": eth_wrapper.owner})
|
492
492
|
ERC1967Proxy = self.get_contract_factory("ERC1967Proxy")
|
493
|
-
init_data = eth_contract.
|
493
|
+
init_data = eth_contract.encode_abi(abi_element_identifier="initialize", args=init_params)
|
494
494
|
proxy_contract = self.construct(
|
495
495
|
ERC1967Proxy,
|
496
496
|
(real_contract.address, init_data),
|
@@ -1,14 +0,0 @@
|
|
1
|
-
ethproto/__init__.py,sha256=YWkAFysBp4tZjLWWB2FFmp5yG23pUYhQvgQW9b3soXs,579
|
2
|
-
ethproto/aa_bundler.py,sha256=PKuWZciyfIqxAZQ30JsKAdICWHLKuU5LDmoL7lCLMqI,9426
|
3
|
-
ethproto/build_artifacts.py,sha256=xwCd5hJUHP82IA-y3sSfX6fV15kjCGtV19RxNRcoor0,5441
|
4
|
-
ethproto/contracts.py,sha256=rNVbCK1hURy7lWKhzSdXgVWo3wx9O_Ghk-6PfgOsRNk,18662
|
5
|
-
ethproto/defender_relay.py,sha256=05A8TfRZwiBhCpo924Pf9CjfKSir2Wvgg1p_asFxJbw,1777
|
6
|
-
ethproto/w3wrappers.py,sha256=nHMunKlmB2BuT03ic9Pk_RcvNsZsBdWQIxQeYnTluVE,21226
|
7
|
-
ethproto/wadray.py,sha256=JBsu5KcyU9k70bDK03T2IY6qPVFO30WbYPhwrAHdXao,8262
|
8
|
-
ethproto/wrappers.py,sha256=9qDwRDOXw3wquzvGfIsub-VPWm98GBWP7dHLFOUPWzg,17307
|
9
|
-
eth_prototype-1.1.1.dist-info/AUTHORS.rst,sha256=Ui-05yYXtDZxna6o1yNcfdm8Jt68UIDQ01osiLxlYlU,95
|
10
|
-
eth_prototype-1.1.1.dist-info/LICENSE.txt,sha256=U_Q6_nDYDwZPIuhttHi37hXZ2qU2-HlV2geo9hzHXFw,1087
|
11
|
-
eth_prototype-1.1.1.dist-info/METADATA,sha256=KYeFLVgwSlTKLtKvwUyzbxjbuoh0wGyRAO36sHvDLO0,2482
|
12
|
-
eth_prototype-1.1.1.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
|
13
|
-
eth_prototype-1.1.1.dist-info/top_level.txt,sha256=Dl0X7m6N1hxeo4JpGpSNqWC2gtsN0731g-DL1J0mpjc,9
|
14
|
-
eth_prototype-1.1.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|