t402 1.9.0__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.
Files changed (100) hide show
  1. t402/__init__.py +2 -1
  2. t402/bridge/client.py +13 -5
  3. t402/bridge/constants.py +3 -1
  4. t402/bridge/router.py +1 -1
  5. t402/bridge/scan.py +3 -1
  6. t402/chains.py +268 -1
  7. t402/cli.py +31 -9
  8. t402/common.py +2 -0
  9. t402/cosmos_paywall_template.py +2 -0
  10. t402/encoding.py +9 -3
  11. t402/erc4337/accounts.py +56 -51
  12. t402/erc4337/bundlers.py +105 -99
  13. t402/erc4337/paymasters.py +100 -109
  14. t402/erc4337/types.py +39 -26
  15. t402/evm_paywall_template.py +1 -1
  16. t402/fastapi/middleware.py +1 -3
  17. t402/mcp/server.py +79 -46
  18. t402/near_paywall_template.py +2 -0
  19. t402/networks.py +34 -1
  20. t402/paywall.py +1 -3
  21. t402/schemes/__init__.py +124 -0
  22. t402/schemes/aptos/__init__.py +70 -0
  23. t402/schemes/aptos/constants.py +349 -0
  24. t402/schemes/aptos/exact_direct/__init__.py +44 -0
  25. t402/schemes/aptos/exact_direct/client.py +202 -0
  26. t402/schemes/aptos/exact_direct/facilitator.py +426 -0
  27. t402/schemes/aptos/exact_direct/server.py +272 -0
  28. t402/schemes/aptos/types.py +237 -0
  29. t402/schemes/evm/__init__.py +46 -1
  30. t402/schemes/evm/exact/__init__.py +11 -0
  31. t402/schemes/evm/exact/client.py +3 -1
  32. t402/schemes/evm/exact/facilitator.py +894 -0
  33. t402/schemes/evm/exact/server.py +1 -1
  34. t402/schemes/evm/exact_legacy/__init__.py +38 -0
  35. t402/schemes/evm/exact_legacy/client.py +291 -0
  36. t402/schemes/evm/exact_legacy/facilitator.py +777 -0
  37. t402/schemes/evm/exact_legacy/server.py +231 -0
  38. t402/schemes/evm/upto/__init__.py +12 -0
  39. t402/schemes/evm/upto/client.py +6 -2
  40. t402/schemes/evm/upto/facilitator.py +625 -0
  41. t402/schemes/evm/upto/server.py +243 -0
  42. t402/schemes/evm/upto/types.py +3 -1
  43. t402/schemes/interfaces.py +6 -2
  44. t402/schemes/near/__init__.py +112 -0
  45. t402/schemes/near/constants.py +189 -0
  46. t402/schemes/near/exact_direct/__init__.py +21 -0
  47. t402/schemes/near/exact_direct/client.py +204 -0
  48. t402/schemes/near/exact_direct/facilitator.py +455 -0
  49. t402/schemes/near/exact_direct/server.py +303 -0
  50. t402/schemes/near/types.py +419 -0
  51. t402/schemes/polkadot/__init__.py +72 -0
  52. t402/schemes/polkadot/constants.py +155 -0
  53. t402/schemes/polkadot/exact_direct/__init__.py +43 -0
  54. t402/schemes/polkadot/exact_direct/client.py +235 -0
  55. t402/schemes/polkadot/exact_direct/facilitator.py +428 -0
  56. t402/schemes/polkadot/exact_direct/server.py +292 -0
  57. t402/schemes/polkadot/types.py +385 -0
  58. t402/schemes/registry.py +6 -2
  59. t402/schemes/stacks/__init__.py +68 -0
  60. t402/schemes/stacks/constants.py +122 -0
  61. t402/schemes/stacks/exact_direct/__init__.py +43 -0
  62. t402/schemes/stacks/exact_direct/client.py +222 -0
  63. t402/schemes/stacks/exact_direct/facilitator.py +424 -0
  64. t402/schemes/stacks/exact_direct/server.py +292 -0
  65. t402/schemes/stacks/types.py +380 -0
  66. t402/schemes/svm/__init__.py +29 -0
  67. t402/schemes/svm/exact/__init__.py +35 -0
  68. t402/schemes/svm/exact/client.py +23 -0
  69. t402/schemes/svm/exact/facilitator.py +24 -0
  70. t402/schemes/svm/exact/server.py +20 -0
  71. t402/schemes/tezos/__init__.py +84 -0
  72. t402/schemes/tezos/constants.py +372 -0
  73. t402/schemes/tezos/exact_direct/__init__.py +22 -0
  74. t402/schemes/tezos/exact_direct/client.py +226 -0
  75. t402/schemes/tezos/exact_direct/facilitator.py +491 -0
  76. t402/schemes/tezos/exact_direct/server.py +277 -0
  77. t402/schemes/tezos/types.py +220 -0
  78. t402/schemes/ton/__init__.py +9 -2
  79. t402/schemes/ton/exact/__init__.py +7 -0
  80. t402/schemes/ton/exact/facilitator.py +730 -0
  81. t402/schemes/ton/exact/server.py +1 -1
  82. t402/schemes/tron/__init__.py +11 -2
  83. t402/schemes/tron/exact/__init__.py +9 -0
  84. t402/schemes/tron/exact/facilitator.py +673 -0
  85. t402/schemes/tron/exact/server.py +1 -1
  86. t402/stacks_paywall_template.py +2 -0
  87. t402/svm.py +45 -11
  88. t402/svm_paywall_template.py +1 -1
  89. t402/ton.py +5 -1
  90. t402/ton_paywall_template.py +1 -192
  91. t402/tron.py +2 -0
  92. t402/tron_paywall_template.py +2 -0
  93. t402/types.py +3 -1
  94. t402/wdk/errors.py +15 -5
  95. t402/wdk/signer.py +11 -2
  96. {t402-1.9.0.dist-info → t402-1.9.1.dist-info}/METADATA +42 -1
  97. t402-1.9.1.dist-info/RECORD +125 -0
  98. t402-1.9.0.dist-info/RECORD +0 -72
  99. {t402-1.9.0.dist-info → t402-1.9.1.dist-info}/WHEEL +0 -0
  100. {t402-1.9.0.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(payment_payload: Union[PaymentPayloadV1, PaymentPayloadV2, dict]) -> str:
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(payment_required: Union[PaymentRequiredV2, dict]) -> str:
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(lower_headers["payment-required"])
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([0xff]) + factory_address + salt_hash + init_code_hash
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(singleton, initializer, self.salt)
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, 'big')
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, 'big')
273
+ result += (96).to_bytes(32, "big")
284
274
 
285
275
  # saltNonce
286
- result += salt_nonce.to_bytes(32, 'big')
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, 'big')
295
+ result += value.to_bytes(32, "big")
310
296
 
311
297
  # offset to data bytes (128)
312
- result += (128).to_bytes(32, 'big')
298
+ result += (128).to_bytes(32, "big")
313
299
 
314
300
  # operation
315
- result += operation.to_bytes(32, 'big')
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, 'big')
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, 'big')
338
+ result += (256).to_bytes(32, "big")
353
339
 
354
340
  # threshold
355
- result += threshold.to_bytes(32, 'big')
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, 'big')
348
+ result += data_offset.to_bytes(32, "big")
363
349
 
364
350
  # fallbackHandler
365
- fh_bytes = bytes.fromhex(fallback_handler[2:]) if fallback_handler.startswith("0x") else bytes.fromhex(fallback_handler)
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 = bytes.fromhex(payment_token[2:]) if payment_token.startswith("0x") else bytes.fromhex(payment_token)
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, 'big')
367
+ result += payment.to_bytes(32, "big")
374
368
 
375
369
  # paymentReceiver
376
- pr_bytes = bytes.fromhex(payment_receiver[2:]) if payment_receiver.startswith("0x") else bytes.fromhex(payment_receiver)
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, 'big')
378
+ result += len(owners).to_bytes(32, "big")
381
379
  for owner in owners:
382
- owner_bytes = bytes.fromhex(owner[2:]) if owner.startswith("0x") else bytes.fromhex(owner)
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, 'big')
399
+ encoded = (32).to_bytes(32, "big")
398
400
 
399
401
  # array length
400
- encoded += len(modules).to_bytes(32, 'big')
402
+ encoded += len(modules).to_bytes(32, "big")
401
403
 
402
404
  # array elements
403
405
  for module in modules:
404
- module_bytes = bytes.fromhex(module[2:]) if module.startswith("0x") else bytes.fromhex(module)
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, 'big')
418
- result += len(data).to_bytes(32, 'big')
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":