t402 1.7.1__py3-none-any.whl → 1.9.1__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.
- t402/__init__.py +2 -1
- t402/bridge/client.py +13 -5
- t402/bridge/constants.py +3 -1
- t402/bridge/router.py +1 -1
- t402/bridge/scan.py +3 -1
- t402/chains.py +268 -1
- t402/cli.py +31 -9
- t402/common.py +2 -0
- t402/cosmos_paywall_template.py +2 -0
- t402/encoding.py +9 -3
- t402/erc4337/accounts.py +56 -51
- t402/erc4337/bundlers.py +105 -99
- t402/erc4337/paymasters.py +100 -109
- t402/erc4337/types.py +39 -26
- t402/evm_paywall_template.py +1 -1
- t402/fastapi/middleware.py +1 -3
- t402/mcp/server.py +79 -46
- t402/near_paywall_template.py +2 -0
- t402/networks.py +34 -1
- t402/paywall.py +1 -3
- t402/schemes/__init__.py +164 -1
- t402/schemes/aptos/__init__.py +70 -0
- t402/schemes/aptos/constants.py +349 -0
- t402/schemes/aptos/exact_direct/__init__.py +44 -0
- t402/schemes/aptos/exact_direct/client.py +202 -0
- t402/schemes/aptos/exact_direct/facilitator.py +426 -0
- t402/schemes/aptos/exact_direct/server.py +272 -0
- t402/schemes/aptos/types.py +237 -0
- t402/schemes/evm/__init__.py +67 -1
- t402/schemes/evm/exact/__init__.py +11 -0
- t402/schemes/evm/exact/client.py +3 -1
- t402/schemes/evm/exact/facilitator.py +894 -0
- t402/schemes/evm/exact/server.py +1 -1
- t402/schemes/evm/exact_legacy/__init__.py +38 -0
- t402/schemes/evm/exact_legacy/client.py +291 -0
- t402/schemes/evm/exact_legacy/facilitator.py +777 -0
- t402/schemes/evm/exact_legacy/server.py +231 -0
- t402/schemes/evm/upto/__init__.py +70 -0
- t402/schemes/evm/upto/client.py +244 -0
- t402/schemes/evm/upto/facilitator.py +625 -0
- t402/schemes/evm/upto/server.py +243 -0
- t402/schemes/evm/upto/types.py +307 -0
- t402/schemes/interfaces.py +6 -2
- t402/schemes/near/__init__.py +112 -0
- t402/schemes/near/constants.py +189 -0
- t402/schemes/near/exact_direct/__init__.py +21 -0
- t402/schemes/near/exact_direct/client.py +204 -0
- t402/schemes/near/exact_direct/facilitator.py +455 -0
- t402/schemes/near/exact_direct/server.py +303 -0
- t402/schemes/near/types.py +419 -0
- t402/schemes/polkadot/__init__.py +72 -0
- t402/schemes/polkadot/constants.py +155 -0
- t402/schemes/polkadot/exact_direct/__init__.py +43 -0
- t402/schemes/polkadot/exact_direct/client.py +235 -0
- t402/schemes/polkadot/exact_direct/facilitator.py +428 -0
- t402/schemes/polkadot/exact_direct/server.py +292 -0
- t402/schemes/polkadot/types.py +385 -0
- t402/schemes/registry.py +6 -2
- t402/schemes/stacks/__init__.py +68 -0
- t402/schemes/stacks/constants.py +122 -0
- t402/schemes/stacks/exact_direct/__init__.py +43 -0
- t402/schemes/stacks/exact_direct/client.py +222 -0
- t402/schemes/stacks/exact_direct/facilitator.py +424 -0
- t402/schemes/stacks/exact_direct/server.py +292 -0
- t402/schemes/stacks/types.py +380 -0
- t402/schemes/svm/__init__.py +29 -0
- t402/schemes/svm/exact/__init__.py +35 -0
- t402/schemes/svm/exact/client.py +23 -0
- t402/schemes/svm/exact/facilitator.py +24 -0
- t402/schemes/svm/exact/server.py +20 -0
- t402/schemes/tezos/__init__.py +84 -0
- t402/schemes/tezos/constants.py +372 -0
- t402/schemes/tezos/exact_direct/__init__.py +22 -0
- t402/schemes/tezos/exact_direct/client.py +226 -0
- t402/schemes/tezos/exact_direct/facilitator.py +491 -0
- t402/schemes/tezos/exact_direct/server.py +277 -0
- t402/schemes/tezos/types.py +220 -0
- t402/schemes/ton/__init__.py +9 -2
- t402/schemes/ton/exact/__init__.py +7 -0
- t402/schemes/ton/exact/facilitator.py +730 -0
- t402/schemes/ton/exact/server.py +1 -1
- t402/schemes/tron/__init__.py +11 -2
- t402/schemes/tron/exact/__init__.py +9 -0
- t402/schemes/tron/exact/facilitator.py +673 -0
- t402/schemes/tron/exact/server.py +1 -1
- t402/schemes/upto/__init__.py +80 -0
- t402/schemes/upto/types.py +376 -0
- t402/stacks_paywall_template.py +2 -0
- t402/svm.py +45 -11
- t402/svm_paywall_template.py +1 -1
- t402/ton.py +5 -1
- t402/ton_paywall_template.py +1 -192
- t402/tron.py +2 -0
- t402/tron_paywall_template.py +2 -0
- t402/types.py +4 -2
- t402/wdk/errors.py +15 -5
- t402/wdk/signer.py +11 -2
- {t402-1.7.1.dist-info → t402-1.9.1.dist-info}/METADATA +42 -1
- t402-1.9.1.dist-info/RECORD +125 -0
- t402-1.7.1.dist-info/RECORD +0 -67
- {t402-1.7.1.dist-info → t402-1.9.1.dist-info}/WHEEL +0 -0
- {t402-1.7.1.dist-info → t402-1.9.1.dist-info}/entry_points.txt +0 -0
t402/erc4337/bundlers.py
CHANGED
|
@@ -47,34 +47,35 @@ class GenericBundlerClient:
|
|
|
47
47
|
def send_user_operation(self, user_op: UserOperation) -> str:
|
|
48
48
|
"""Submit a UserOperation to the bundler."""
|
|
49
49
|
packed = user_op.to_packed_dict()
|
|
50
|
-
result = self._rpc_call(
|
|
51
|
-
"eth_sendUserOperation",
|
|
52
|
-
[packed, self.entry_point]
|
|
53
|
-
)
|
|
50
|
+
result = self._rpc_call("eth_sendUserOperation", [packed, self.entry_point])
|
|
54
51
|
return result
|
|
55
52
|
|
|
56
53
|
def estimate_user_operation_gas(self, user_op: UserOperation) -> GasEstimate:
|
|
57
54
|
"""Estimate gas for a UserOperation."""
|
|
58
55
|
packed = user_op.to_packed_dict()
|
|
59
56
|
result = self._rpc_call(
|
|
60
|
-
"eth_estimateUserOperationGas",
|
|
61
|
-
[packed, self.entry_point]
|
|
57
|
+
"eth_estimateUserOperationGas", [packed, self.entry_point]
|
|
62
58
|
)
|
|
63
59
|
|
|
64
60
|
return GasEstimate(
|
|
65
61
|
verification_gas_limit=int(result.get("verificationGasLimit", "0x0"), 16),
|
|
66
62
|
call_gas_limit=int(result.get("callGasLimit", "0x0"), 16),
|
|
67
63
|
pre_verification_gas=int(result.get("preVerificationGas", "0x0"), 16),
|
|
68
|
-
paymaster_verification_gas_limit=int(
|
|
69
|
-
|
|
64
|
+
paymaster_verification_gas_limit=int(
|
|
65
|
+
result.get("paymasterVerificationGasLimit", "0x0"), 16
|
|
66
|
+
)
|
|
67
|
+
if result.get("paymasterVerificationGasLimit")
|
|
68
|
+
else None,
|
|
69
|
+
paymaster_post_op_gas_limit=int(
|
|
70
|
+
result.get("paymasterPostOpGasLimit", "0x0"), 16
|
|
71
|
+
)
|
|
72
|
+
if result.get("paymasterPostOpGasLimit")
|
|
73
|
+
else None,
|
|
70
74
|
)
|
|
71
75
|
|
|
72
76
|
def get_user_operation_by_hash(self, user_op_hash: str) -> Optional[UserOperation]:
|
|
73
77
|
"""Retrieve a UserOperation by hash."""
|
|
74
|
-
result = self._rpc_call(
|
|
75
|
-
"eth_getUserOperationByHash",
|
|
76
|
-
[user_op_hash]
|
|
77
|
-
)
|
|
78
|
+
result = self._rpc_call("eth_getUserOperationByHash", [user_op_hash])
|
|
78
79
|
|
|
79
80
|
if not result or not result.get("userOperation"):
|
|
80
81
|
return None
|
|
@@ -94,12 +95,11 @@ class GenericBundlerClient:
|
|
|
94
95
|
signature=bytes.fromhex(op.get("signature", "0x")[2:]),
|
|
95
96
|
)
|
|
96
97
|
|
|
97
|
-
def get_user_operation_receipt(
|
|
98
|
+
def get_user_operation_receipt(
|
|
99
|
+
self, user_op_hash: str
|
|
100
|
+
) -> Optional[UserOperationReceipt]:
|
|
98
101
|
"""Retrieve the receipt for a UserOperation."""
|
|
99
|
-
result = self._rpc_call(
|
|
100
|
-
"eth_getUserOperationReceipt",
|
|
101
|
-
[user_op_hash]
|
|
102
|
-
)
|
|
102
|
+
result = self._rpc_call("eth_getUserOperationReceipt", [user_op_hash])
|
|
103
103
|
|
|
104
104
|
if not result or not result.get("userOpHash"):
|
|
105
105
|
return None
|
|
@@ -115,7 +115,9 @@ class GenericBundlerClient:
|
|
|
115
115
|
success=result.get("success", False),
|
|
116
116
|
reason=result.get("reason"),
|
|
117
117
|
transaction_hash=receipt.get("transactionHash"),
|
|
118
|
-
block_number=int(receipt.get("blockNumber", "0x0"), 16)
|
|
118
|
+
block_number=int(receipt.get("blockNumber", "0x0"), 16)
|
|
119
|
+
if receipt.get("blockNumber")
|
|
120
|
+
else None,
|
|
119
121
|
block_hash=receipt.get("blockHash"),
|
|
120
122
|
)
|
|
121
123
|
|
|
@@ -125,10 +127,7 @@ class GenericBundlerClient:
|
|
|
125
127
|
return result or []
|
|
126
128
|
|
|
127
129
|
def wait_for_receipt(
|
|
128
|
-
self,
|
|
129
|
-
user_op_hash: str,
|
|
130
|
-
timeout: float = 60.0,
|
|
131
|
-
polling_interval: float = 2.0
|
|
130
|
+
self, user_op_hash: str, timeout: float = 60.0, polling_interval: float = 2.0
|
|
132
131
|
) -> UserOperationReceipt:
|
|
133
132
|
"""Wait for a UserOperation receipt with polling."""
|
|
134
133
|
deadline = time.time() + timeout
|
|
@@ -153,9 +152,7 @@ class GenericBundlerClient:
|
|
|
153
152
|
}
|
|
154
153
|
|
|
155
154
|
response = self._client.post(
|
|
156
|
-
self.bundler_url,
|
|
157
|
-
json=request,
|
|
158
|
-
headers={"Content-Type": "application/json"}
|
|
155
|
+
self.bundler_url, json=request, headers={"Content-Type": "application/json"}
|
|
159
156
|
)
|
|
160
157
|
|
|
161
158
|
if response.status_code != 200:
|
|
@@ -168,7 +165,7 @@ class GenericBundlerClient:
|
|
|
168
165
|
raise BundlerError(
|
|
169
166
|
error.get("message", "Unknown error"),
|
|
170
167
|
code=error.get("code"),
|
|
171
|
-
data=error.get("data")
|
|
168
|
+
data=error.get("data"),
|
|
172
169
|
)
|
|
173
170
|
|
|
174
171
|
return data.get("result")
|
|
@@ -177,6 +174,7 @@ class GenericBundlerClient:
|
|
|
177
174
|
@dataclass
|
|
178
175
|
class PimlicoGasPrice:
|
|
179
176
|
"""Gas price estimates from Pimlico."""
|
|
177
|
+
|
|
180
178
|
slow_max_fee: int
|
|
181
179
|
slow_priority_fee: int
|
|
182
180
|
standard_max_fee: int
|
|
@@ -193,16 +191,14 @@ class PimlicoBundlerClient(GenericBundlerClient):
|
|
|
193
191
|
api_key: str,
|
|
194
192
|
chain_id: int,
|
|
195
193
|
bundler_url: Optional[str] = None,
|
|
196
|
-
entry_point: str = ENTRYPOINT_V07_ADDRESS
|
|
194
|
+
entry_point: str = ENTRYPOINT_V07_ADDRESS,
|
|
197
195
|
):
|
|
198
196
|
network = PIMLICO_NETWORKS.get(chain_id, str(chain_id))
|
|
199
197
|
url = bundler_url or f"https://api.pimlico.io/v2/{network}/rpc?apikey={api_key}"
|
|
200
198
|
|
|
201
|
-
super().__init__(
|
|
202
|
-
bundler_url=url,
|
|
203
|
-
|
|
204
|
-
entry_point=entry_point
|
|
205
|
-
))
|
|
199
|
+
super().__init__(
|
|
200
|
+
BundlerConfig(bundler_url=url, chain_id=chain_id, entry_point=entry_point)
|
|
201
|
+
)
|
|
206
202
|
|
|
207
203
|
self.api_key = api_key
|
|
208
204
|
|
|
@@ -220,39 +216,32 @@ class PimlicoBundlerClient(GenericBundlerClient):
|
|
|
220
216
|
)
|
|
221
217
|
|
|
222
218
|
def send_compressed_user_operation(
|
|
223
|
-
self,
|
|
224
|
-
compressed_calldata: bytes,
|
|
225
|
-
inflator_address: str
|
|
219
|
+
self, compressed_calldata: bytes, inflator_address: str
|
|
226
220
|
) -> str:
|
|
227
221
|
"""Send a compressed UserOperation for gas savings."""
|
|
228
222
|
result = self._rpc_call(
|
|
229
223
|
"pimlico_sendCompressedUserOperation",
|
|
230
|
-
[
|
|
231
|
-
"0x" + compressed_calldata.hex(),
|
|
232
|
-
inflator_address,
|
|
233
|
-
self.entry_point
|
|
234
|
-
]
|
|
224
|
+
["0x" + compressed_calldata.hex(), inflator_address, self.entry_point],
|
|
235
225
|
)
|
|
236
226
|
return result
|
|
237
227
|
|
|
238
228
|
def get_user_operation_status(self, user_op_hash: str) -> Dict[str, Any]:
|
|
239
229
|
"""Get the status of a UserOperation."""
|
|
240
|
-
result = self._rpc_call(
|
|
241
|
-
"pimlico_getUserOperationStatus",
|
|
242
|
-
[user_op_hash]
|
|
243
|
-
)
|
|
230
|
+
result = self._rpc_call("pimlico_getUserOperationStatus", [user_op_hash])
|
|
244
231
|
return result
|
|
245
232
|
|
|
246
233
|
|
|
247
234
|
@dataclass
|
|
248
235
|
class AlchemyPolicyConfig:
|
|
249
236
|
"""Alchemy policy configuration for gas sponsorship."""
|
|
237
|
+
|
|
250
238
|
policy_id: str
|
|
251
239
|
|
|
252
240
|
|
|
253
241
|
@dataclass
|
|
254
242
|
class GasAndPaymasterResult:
|
|
255
243
|
"""Combined gas and paymaster data from Alchemy."""
|
|
244
|
+
|
|
256
245
|
gas_estimate: GasEstimate
|
|
257
246
|
paymaster_data: Optional[PaymasterData]
|
|
258
247
|
max_fee_per_gas: int
|
|
@@ -268,7 +257,7 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
268
257
|
chain_id: int,
|
|
269
258
|
bundler_url: Optional[str] = None,
|
|
270
259
|
entry_point: str = ENTRYPOINT_V07_ADDRESS,
|
|
271
|
-
policy: Optional[AlchemyPolicyConfig] = None
|
|
260
|
+
policy: Optional[AlchemyPolicyConfig] = None,
|
|
272
261
|
):
|
|
273
262
|
network = ALCHEMY_NETWORKS.get(chain_id)
|
|
274
263
|
if not network:
|
|
@@ -276,19 +265,15 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
276
265
|
|
|
277
266
|
url = bundler_url or f"https://{network}.g.alchemy.com/v2/{api_key}"
|
|
278
267
|
|
|
279
|
-
super().__init__(
|
|
280
|
-
bundler_url=url,
|
|
281
|
-
|
|
282
|
-
entry_point=entry_point
|
|
283
|
-
))
|
|
268
|
+
super().__init__(
|
|
269
|
+
BundlerConfig(bundler_url=url, chain_id=chain_id, entry_point=entry_point)
|
|
270
|
+
)
|
|
284
271
|
|
|
285
272
|
self.api_key = api_key
|
|
286
273
|
self.policy = policy
|
|
287
274
|
|
|
288
275
|
def request_gas_and_paymaster_and_data(
|
|
289
|
-
self,
|
|
290
|
-
user_op: UserOperation,
|
|
291
|
-
overrides: Optional[Dict[str, int]] = None
|
|
276
|
+
self, user_op: UserOperation, overrides: Optional[Dict[str, int]] = None
|
|
292
277
|
) -> GasAndPaymasterResult:
|
|
293
278
|
"""Request gas estimates and paymaster data in a single call."""
|
|
294
279
|
if not self.policy:
|
|
@@ -304,33 +289,42 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
304
289
|
}
|
|
305
290
|
|
|
306
291
|
if overrides:
|
|
307
|
-
request_params["overrides"] = {
|
|
308
|
-
k: hex(v) for k, v in overrides.items()
|
|
309
|
-
}
|
|
292
|
+
request_params["overrides"] = {k: hex(v) for k, v in overrides.items()}
|
|
310
293
|
|
|
311
294
|
result = self._rpc_call(
|
|
312
|
-
"alchemy_requestGasAndPaymasterAndData",
|
|
313
|
-
[request_params]
|
|
295
|
+
"alchemy_requestGasAndPaymasterAndData", [request_params]
|
|
314
296
|
)
|
|
315
297
|
|
|
316
298
|
# Parse paymaster data
|
|
317
299
|
paymaster_data = None
|
|
318
300
|
paymaster_and_data = result.get("paymasterAndData", "0x")
|
|
319
|
-
if
|
|
301
|
+
if (
|
|
302
|
+
paymaster_and_data
|
|
303
|
+
and paymaster_and_data != "0x"
|
|
304
|
+
and len(paymaster_and_data) >= 106
|
|
305
|
+
):
|
|
320
306
|
paymaster_data = PaymasterData(
|
|
321
307
|
paymaster="0x" + paymaster_and_data[2:42],
|
|
322
308
|
paymaster_verification_gas_limit=int(paymaster_and_data[42:74], 16),
|
|
323
309
|
paymaster_post_op_gas_limit=int(paymaster_and_data[74:106], 16),
|
|
324
|
-
paymaster_data=bytes.fromhex(paymaster_and_data[106:])
|
|
310
|
+
paymaster_data=bytes.fromhex(paymaster_and_data[106:])
|
|
311
|
+
if len(paymaster_and_data) > 106
|
|
312
|
+
else b"",
|
|
325
313
|
)
|
|
326
314
|
|
|
327
315
|
return GasAndPaymasterResult(
|
|
328
316
|
gas_estimate=GasEstimate(
|
|
329
|
-
verification_gas_limit=int(
|
|
317
|
+
verification_gas_limit=int(
|
|
318
|
+
result.get("verificationGasLimit", "0x0"), 16
|
|
319
|
+
),
|
|
330
320
|
call_gas_limit=int(result.get("callGasLimit", "0x0"), 16),
|
|
331
321
|
pre_verification_gas=int(result.get("preVerificationGas", "0x0"), 16),
|
|
332
|
-
paymaster_verification_gas_limit=paymaster_data.paymaster_verification_gas_limit
|
|
333
|
-
|
|
322
|
+
paymaster_verification_gas_limit=paymaster_data.paymaster_verification_gas_limit
|
|
323
|
+
if paymaster_data
|
|
324
|
+
else None,
|
|
325
|
+
paymaster_post_op_gas_limit=paymaster_data.paymaster_post_op_gas_limit
|
|
326
|
+
if paymaster_data
|
|
327
|
+
else None,
|
|
334
328
|
),
|
|
335
329
|
paymaster_data=paymaster_data,
|
|
336
330
|
max_fee_per_gas=int(result.get("maxFeePerGas", "0x0"), 16),
|
|
@@ -338,8 +332,7 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
338
332
|
)
|
|
339
333
|
|
|
340
334
|
def simulate_user_operation_asset_changes(
|
|
341
|
-
self,
|
|
342
|
-
user_op: UserOperation
|
|
335
|
+
self, user_op: UserOperation
|
|
343
336
|
) -> SimulationResult:
|
|
344
337
|
"""Simulate asset changes from a UserOperation."""
|
|
345
338
|
packed = user_op.to_packed_dict()
|
|
@@ -347,26 +340,34 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
347
340
|
try:
|
|
348
341
|
result = self._rpc_call(
|
|
349
342
|
"alchemy_simulateUserOperationAssetChanges",
|
|
350
|
-
[
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
343
|
+
[
|
|
344
|
+
{
|
|
345
|
+
"entryPoint": self.entry_point,
|
|
346
|
+
"userOperation": packed,
|
|
347
|
+
}
|
|
348
|
+
],
|
|
354
349
|
)
|
|
355
350
|
|
|
356
351
|
changes = []
|
|
357
352
|
for change in result.get("changes", []):
|
|
358
|
-
changes.append(
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
353
|
+
changes.append(
|
|
354
|
+
AssetChange(
|
|
355
|
+
asset_type=change.get("assetType", ""),
|
|
356
|
+
change_type=change.get("changeType", ""),
|
|
357
|
+
from_address=change.get("from", ""),
|
|
358
|
+
to_address=change.get("to", ""),
|
|
359
|
+
amount=int(change["amount"], 16)
|
|
360
|
+
if change.get("amount")
|
|
361
|
+
else None,
|
|
362
|
+
token_id=int(change["tokenId"], 16)
|
|
363
|
+
if change.get("tokenId")
|
|
364
|
+
else None,
|
|
365
|
+
contract_address=change.get("contractAddress"),
|
|
366
|
+
symbol=change.get("symbol"),
|
|
367
|
+
name=change.get("name"),
|
|
368
|
+
decimals=change.get("decimals"),
|
|
369
|
+
)
|
|
370
|
+
)
|
|
370
371
|
|
|
371
372
|
return SimulationResult(success=True, changes=changes)
|
|
372
373
|
|
|
@@ -375,10 +376,7 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
375
376
|
|
|
376
377
|
def get_fee_history(self) -> Dict[str, int]:
|
|
377
378
|
"""Get fee history for gas estimation."""
|
|
378
|
-
result = self._rpc_call(
|
|
379
|
-
"eth_feeHistory",
|
|
380
|
-
["0x5", "latest", [25, 50, 75]]
|
|
381
|
-
)
|
|
379
|
+
result = self._rpc_call("eth_feeHistory", ["0x5", "latest", [25, 50, 75]])
|
|
382
380
|
|
|
383
381
|
base_fee_per_gas = result.get("baseFeePerGas", [])
|
|
384
382
|
rewards = result.get("reward", [])
|
|
@@ -390,7 +388,12 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
390
388
|
if rewards:
|
|
391
389
|
mid_idx = len(rewards) // 2
|
|
392
390
|
if rewards[mid_idx]:
|
|
393
|
-
median_priority_fee = int(
|
|
391
|
+
median_priority_fee = int(
|
|
392
|
+
rewards[mid_idx][1]
|
|
393
|
+
if len(rewards[mid_idx]) > 1
|
|
394
|
+
else rewards[mid_idx][0],
|
|
395
|
+
16,
|
|
396
|
+
)
|
|
394
397
|
|
|
395
398
|
max_fee_per_gas = latest_base_fee * 2 + median_priority_fee
|
|
396
399
|
|
|
@@ -407,8 +410,12 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
407
410
|
"nonce": hex(user_op.nonce),
|
|
408
411
|
"initCode": "0x" + user_op.init_code.hex() if user_op.init_code else "0x",
|
|
409
412
|
"callData": "0x" + user_op.call_data.hex() if user_op.call_data else "0x",
|
|
410
|
-
"paymasterAndData": "0x" + user_op.paymaster_and_data.hex()
|
|
411
|
-
|
|
413
|
+
"paymasterAndData": "0x" + user_op.paymaster_and_data.hex()
|
|
414
|
+
if user_op.paymaster_and_data
|
|
415
|
+
else "0x",
|
|
416
|
+
"signature": "0x" + user_op.signature.hex()
|
|
417
|
+
if user_op.signature
|
|
418
|
+
else "0x" + get_dummy_signature().hex(),
|
|
412
419
|
}
|
|
413
420
|
|
|
414
421
|
if user_op.verification_gas_limit:
|
|
@@ -426,10 +433,7 @@ class AlchemyBundlerClient(GenericBundlerClient):
|
|
|
426
433
|
|
|
427
434
|
|
|
428
435
|
def create_bundler_client(
|
|
429
|
-
provider: str,
|
|
430
|
-
api_key: str,
|
|
431
|
-
chain_id: int,
|
|
432
|
-
**kwargs
|
|
436
|
+
provider: str, api_key: str, chain_id: int, **kwargs
|
|
433
437
|
) -> Union[GenericBundlerClient, PimlicoBundlerClient, AlchemyBundlerClient]:
|
|
434
438
|
"""Factory function to create a bundler client."""
|
|
435
439
|
if provider == "pimlico":
|
|
@@ -437,7 +441,7 @@ def create_bundler_client(
|
|
|
437
441
|
api_key=api_key,
|
|
438
442
|
chain_id=chain_id,
|
|
439
443
|
bundler_url=kwargs.get("bundler_url"),
|
|
440
|
-
entry_point=kwargs.get("entry_point", ENTRYPOINT_V07_ADDRESS)
|
|
444
|
+
entry_point=kwargs.get("entry_point", ENTRYPOINT_V07_ADDRESS),
|
|
441
445
|
)
|
|
442
446
|
elif provider == "alchemy":
|
|
443
447
|
policy = None
|
|
@@ -448,11 +452,13 @@ def create_bundler_client(
|
|
|
448
452
|
chain_id=chain_id,
|
|
449
453
|
bundler_url=kwargs.get("bundler_url"),
|
|
450
454
|
entry_point=kwargs.get("entry_point", ENTRYPOINT_V07_ADDRESS),
|
|
451
|
-
policy=policy
|
|
455
|
+
policy=policy,
|
|
452
456
|
)
|
|
453
457
|
else:
|
|
454
|
-
return GenericBundlerClient(
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
458
|
+
return GenericBundlerClient(
|
|
459
|
+
BundlerConfig(
|
|
460
|
+
bundler_url=kwargs.get("bundler_url", ""),
|
|
461
|
+
chain_id=chain_id,
|
|
462
|
+
entry_point=kwargs.get("entry_point", ENTRYPOINT_V07_ADDRESS),
|
|
463
|
+
)
|
|
464
|
+
)
|