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/encoding.py
CHANGED
|
@@ -88,7 +88,9 @@ def is_valid_base64(data: str) -> bool:
|
|
|
88
88
|
# =============================================================================
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
def encode_payment_signature_header(
|
|
91
|
+
def encode_payment_signature_header(
|
|
92
|
+
payment_payload: Union[PaymentPayloadV1, PaymentPayloadV2, dict],
|
|
93
|
+
) -> str:
|
|
92
94
|
"""Encode a payment payload as a base64 header value.
|
|
93
95
|
|
|
94
96
|
Works with both V1 and V2 payment payloads.
|
|
@@ -129,7 +131,9 @@ def decode_payment_signature_header(header_value: str) -> dict[str, Any]:
|
|
|
129
131
|
raise ValueError(f"Invalid payment signature header: invalid JSON - {e}")
|
|
130
132
|
|
|
131
133
|
|
|
132
|
-
def encode_payment_required_header(
|
|
134
|
+
def encode_payment_required_header(
|
|
135
|
+
payment_required: Union[PaymentRequiredV2, dict],
|
|
136
|
+
) -> str:
|
|
133
137
|
"""Encode a payment required object as a base64 header value.
|
|
134
138
|
|
|
135
139
|
Args:
|
|
@@ -314,7 +318,9 @@ def extract_payment_required_from_response(
|
|
|
314
318
|
# Check V2 header first
|
|
315
319
|
if "payment-required" in lower_headers:
|
|
316
320
|
try:
|
|
317
|
-
return T402_VERSION_V2, decode_payment_required_header(
|
|
321
|
+
return T402_VERSION_V2, decode_payment_required_header(
|
|
322
|
+
lower_headers["payment-required"]
|
|
323
|
+
)
|
|
318
324
|
except ValueError:
|
|
319
325
|
pass
|
|
320
326
|
|
t402/erc4337/accounts.py
CHANGED
|
@@ -20,6 +20,7 @@ from .types import (
|
|
|
20
20
|
|
|
21
21
|
class SmartAccountError(Exception):
|
|
22
22
|
"""Error from smart account operations."""
|
|
23
|
+
|
|
23
24
|
pass
|
|
24
25
|
|
|
25
26
|
|
|
@@ -53,10 +54,7 @@ class SmartAccountSigner(ABC):
|
|
|
53
54
|
|
|
54
55
|
@abstractmethod
|
|
55
56
|
def encode_execute_batch(
|
|
56
|
-
self,
|
|
57
|
-
targets: List[str],
|
|
58
|
-
values: List[int],
|
|
59
|
-
datas: List[bytes]
|
|
57
|
+
self, targets: List[str], values: List[int], datas: List[bytes]
|
|
60
58
|
) -> bytes:
|
|
61
59
|
"""Encode a batch call to the account's executeBatch function."""
|
|
62
60
|
pass
|
|
@@ -65,6 +63,7 @@ class SmartAccountSigner(ABC):
|
|
|
65
63
|
@dataclass
|
|
66
64
|
class SafeAccountConfig:
|
|
67
65
|
"""Configuration for Safe smart account."""
|
|
66
|
+
|
|
68
67
|
owner_private_key: str
|
|
69
68
|
chain_id: int
|
|
70
69
|
salt: int = 0
|
|
@@ -101,7 +100,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
101
100
|
init_code_hash = keccak(proxy_init_code)
|
|
102
101
|
|
|
103
102
|
# CREATE2 address: keccak256(0xff ++ factory ++ salt ++ keccak256(initCode))[12:]
|
|
104
|
-
data = bytes([
|
|
103
|
+
data = bytes([0xFF]) + factory_address + salt_hash + init_code_hash
|
|
105
104
|
address_hash = keccak(data)
|
|
106
105
|
|
|
107
106
|
self._cached_address = "0x" + address_hash[12:].hex()
|
|
@@ -113,9 +112,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
113
112
|
message_hash = self._get_safe_user_op_hash(user_op_hash)
|
|
114
113
|
|
|
115
114
|
# Sign with owner key
|
|
116
|
-
signed = self.owner_account.sign_message(
|
|
117
|
-
encode_defunct(primitive=message_hash)
|
|
118
|
-
)
|
|
115
|
+
signed = self.owner_account.sign_message(encode_defunct(primitive=message_hash))
|
|
119
116
|
|
|
120
117
|
return signed.signature
|
|
121
118
|
|
|
@@ -135,7 +132,9 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
135
132
|
|
|
136
133
|
# ABI encode the parameters
|
|
137
134
|
singleton = bytes.fromhex(SAFE_4337_ADDRESSES["singleton"][2:])
|
|
138
|
-
encoded = self._encode_create_proxy_with_nonce(
|
|
135
|
+
encoded = self._encode_create_proxy_with_nonce(
|
|
136
|
+
singleton, initializer, self.salt
|
|
137
|
+
)
|
|
139
138
|
|
|
140
139
|
self._cached_init_code = factory_address + selector + encoded
|
|
141
140
|
return self._cached_init_code
|
|
@@ -160,10 +159,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
160
159
|
return selector + encoded
|
|
161
160
|
|
|
162
161
|
def encode_execute_batch(
|
|
163
|
-
self,
|
|
164
|
-
targets: List[str],
|
|
165
|
-
values: List[int],
|
|
166
|
-
datas: List[bytes]
|
|
162
|
+
self, targets: List[str], values: List[int], datas: List[bytes]
|
|
167
163
|
) -> bytes:
|
|
168
164
|
"""Encode a batch call using multiSend."""
|
|
169
165
|
if len(targets) != len(values) or len(targets) != len(datas):
|
|
@@ -186,10 +182,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
186
182
|
operation = 1 # DELEGATECALL
|
|
187
183
|
|
|
188
184
|
encoded = self._encode_execute_user_op(
|
|
189
|
-
self.MULTI_SEND_ADDRESS,
|
|
190
|
-
0,
|
|
191
|
-
multi_send_calldata,
|
|
192
|
-
operation
|
|
185
|
+
self.MULTI_SEND_ADDRESS, 0, multi_send_calldata, operation
|
|
193
186
|
)
|
|
194
187
|
|
|
195
188
|
return selector + encoded
|
|
@@ -232,7 +225,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
232
225
|
fallback_handler,
|
|
233
226
|
payment_token,
|
|
234
227
|
payment,
|
|
235
|
-
payment_receiver
|
|
228
|
+
payment_receiver,
|
|
236
229
|
)
|
|
237
230
|
|
|
238
231
|
return selector + encoded
|
|
@@ -243,7 +236,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
243
236
|
initializer = self._build_initializer()
|
|
244
237
|
init_hash = keccak(initializer)
|
|
245
238
|
|
|
246
|
-
salt_bytes = self.salt.to_bytes(32,
|
|
239
|
+
salt_bytes = self.salt.to_bytes(32, "big")
|
|
247
240
|
salt_data = init_hash + salt_bytes
|
|
248
241
|
|
|
249
242
|
return keccak(salt_data)
|
|
@@ -267,10 +260,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
267
260
|
return user_op_hash
|
|
268
261
|
|
|
269
262
|
def _encode_create_proxy_with_nonce(
|
|
270
|
-
self,
|
|
271
|
-
singleton: bytes,
|
|
272
|
-
initializer: bytes,
|
|
273
|
-
salt_nonce: int
|
|
263
|
+
self, singleton: bytes, initializer: bytes, salt_nonce: int
|
|
274
264
|
) -> bytes:
|
|
275
265
|
"""ABI encode createProxyWithNonce parameters."""
|
|
276
266
|
# (address, bytes, uint256)
|
|
@@ -280,10 +270,10 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
280
270
|
result += singleton.rjust(32, b"\x00")
|
|
281
271
|
|
|
282
272
|
# offset to initializer bytes (96)
|
|
283
|
-
result += (96).to_bytes(32,
|
|
273
|
+
result += (96).to_bytes(32, "big")
|
|
284
274
|
|
|
285
275
|
# saltNonce
|
|
286
|
-
result += salt_nonce.to_bytes(32,
|
|
276
|
+
result += salt_nonce.to_bytes(32, "big")
|
|
287
277
|
|
|
288
278
|
# initializer bytes
|
|
289
279
|
result += self._encode_bytes(initializer)
|
|
@@ -291,11 +281,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
291
281
|
return result
|
|
292
282
|
|
|
293
283
|
def _encode_execute_user_op(
|
|
294
|
-
self,
|
|
295
|
-
to: str,
|
|
296
|
-
value: int,
|
|
297
|
-
data: bytes,
|
|
298
|
-
operation: int
|
|
284
|
+
self, to: str, value: int, data: bytes, operation: int
|
|
299
285
|
) -> bytes:
|
|
300
286
|
"""ABI encode executeUserOp parameters."""
|
|
301
287
|
# (address, uint256, bytes, uint8)
|
|
@@ -306,13 +292,13 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
306
292
|
result += to_bytes.rjust(32, b"\x00")
|
|
307
293
|
|
|
308
294
|
# value
|
|
309
|
-
result += value.to_bytes(32,
|
|
295
|
+
result += value.to_bytes(32, "big")
|
|
310
296
|
|
|
311
297
|
# offset to data bytes (128)
|
|
312
|
-
result += (128).to_bytes(32,
|
|
298
|
+
result += (128).to_bytes(32, "big")
|
|
313
299
|
|
|
314
300
|
# operation
|
|
315
|
-
result += operation.to_bytes(32,
|
|
301
|
+
result += operation.to_bytes(32, "big")
|
|
316
302
|
|
|
317
303
|
# data bytes
|
|
318
304
|
result += self._encode_bytes(data)
|
|
@@ -325,7 +311,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
325
311
|
length = len(data)
|
|
326
312
|
padded_length = ((length + 31) // 32) * 32
|
|
327
313
|
|
|
328
|
-
result = length.to_bytes(32,
|
|
314
|
+
result = length.to_bytes(32, "big")
|
|
329
315
|
result += data.ljust(padded_length, b"\x00")
|
|
330
316
|
|
|
331
317
|
return result
|
|
@@ -339,7 +325,7 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
339
325
|
fallback_handler: str,
|
|
340
326
|
payment_token: str,
|
|
341
327
|
payment: int,
|
|
342
|
-
payment_receiver: str
|
|
328
|
+
payment_receiver: str,
|
|
343
329
|
) -> bytes:
|
|
344
330
|
"""ABI encode Safe.setup parameters."""
|
|
345
331
|
result = b""
|
|
@@ -349,37 +335,53 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
349
335
|
data_offset = 256 + owners_encoded_len
|
|
350
336
|
|
|
351
337
|
# offset to owners array (256)
|
|
352
|
-
result += (256).to_bytes(32,
|
|
338
|
+
result += (256).to_bytes(32, "big")
|
|
353
339
|
|
|
354
340
|
# threshold
|
|
355
|
-
result += threshold.to_bytes(32,
|
|
341
|
+
result += threshold.to_bytes(32, "big")
|
|
356
342
|
|
|
357
343
|
# to
|
|
358
344
|
to_bytes = bytes.fromhex(to[2:]) if to.startswith("0x") else bytes.fromhex(to)
|
|
359
345
|
result += to_bytes.rjust(32, b"\x00")
|
|
360
346
|
|
|
361
347
|
# data offset
|
|
362
|
-
result += data_offset.to_bytes(32,
|
|
348
|
+
result += data_offset.to_bytes(32, "big")
|
|
363
349
|
|
|
364
350
|
# fallbackHandler
|
|
365
|
-
fh_bytes =
|
|
351
|
+
fh_bytes = (
|
|
352
|
+
bytes.fromhex(fallback_handler[2:])
|
|
353
|
+
if fallback_handler.startswith("0x")
|
|
354
|
+
else bytes.fromhex(fallback_handler)
|
|
355
|
+
)
|
|
366
356
|
result += fh_bytes.rjust(32, b"\x00")
|
|
367
357
|
|
|
368
358
|
# paymentToken
|
|
369
|
-
pt_bytes =
|
|
359
|
+
pt_bytes = (
|
|
360
|
+
bytes.fromhex(payment_token[2:])
|
|
361
|
+
if payment_token.startswith("0x")
|
|
362
|
+
else bytes.fromhex(payment_token)
|
|
363
|
+
)
|
|
370
364
|
result += pt_bytes.rjust(32, b"\x00")
|
|
371
365
|
|
|
372
366
|
# payment
|
|
373
|
-
result += payment.to_bytes(32,
|
|
367
|
+
result += payment.to_bytes(32, "big")
|
|
374
368
|
|
|
375
369
|
# paymentReceiver
|
|
376
|
-
pr_bytes =
|
|
370
|
+
pr_bytes = (
|
|
371
|
+
bytes.fromhex(payment_receiver[2:])
|
|
372
|
+
if payment_receiver.startswith("0x")
|
|
373
|
+
else bytes.fromhex(payment_receiver)
|
|
374
|
+
)
|
|
377
375
|
result += pr_bytes.rjust(32, b"\x00")
|
|
378
376
|
|
|
379
377
|
# owners array
|
|
380
|
-
result += len(owners).to_bytes(32,
|
|
378
|
+
result += len(owners).to_bytes(32, "big")
|
|
381
379
|
for owner in owners:
|
|
382
|
-
owner_bytes =
|
|
380
|
+
owner_bytes = (
|
|
381
|
+
bytes.fromhex(owner[2:])
|
|
382
|
+
if owner.startswith("0x")
|
|
383
|
+
else bytes.fromhex(owner)
|
|
384
|
+
)
|
|
383
385
|
result += owner_bytes.rjust(32, b"\x00")
|
|
384
386
|
|
|
385
387
|
# data bytes
|
|
@@ -394,14 +396,18 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
394
396
|
selector = bytes.fromhex("a3f4df7e")
|
|
395
397
|
|
|
396
398
|
# offset to array (32)
|
|
397
|
-
encoded = (32).to_bytes(32,
|
|
399
|
+
encoded = (32).to_bytes(32, "big")
|
|
398
400
|
|
|
399
401
|
# array length
|
|
400
|
-
encoded += len(modules).to_bytes(32,
|
|
402
|
+
encoded += len(modules).to_bytes(32, "big")
|
|
401
403
|
|
|
402
404
|
# array elements
|
|
403
405
|
for module in modules:
|
|
404
|
-
module_bytes =
|
|
406
|
+
module_bytes = (
|
|
407
|
+
bytes.fromhex(module[2:])
|
|
408
|
+
if module.startswith("0x")
|
|
409
|
+
else bytes.fromhex(module)
|
|
410
|
+
)
|
|
405
411
|
encoded += module_bytes.rjust(32, b"\x00")
|
|
406
412
|
|
|
407
413
|
return selector + encoded
|
|
@@ -414,16 +420,15 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
414
420
|
to_bytes = bytes.fromhex(to[2:]) if to.startswith("0x") else bytes.fromhex(to)
|
|
415
421
|
result += to_bytes
|
|
416
422
|
|
|
417
|
-
result += value.to_bytes(32,
|
|
418
|
-
result += len(data).to_bytes(32,
|
|
423
|
+
result += value.to_bytes(32, "big")
|
|
424
|
+
result += len(data).to_bytes(32, "big")
|
|
419
425
|
result += data
|
|
420
426
|
|
|
421
427
|
return result
|
|
422
428
|
|
|
423
429
|
|
|
424
430
|
def create_smart_account(
|
|
425
|
-
account_type: str,
|
|
426
|
-
config: SafeAccountConfig
|
|
431
|
+
account_type: str, config: SafeAccountConfig
|
|
427
432
|
) -> SmartAccountSigner:
|
|
428
433
|
"""Factory function to create a smart account."""
|
|
429
434
|
if account_type == "safe":
|