t402 1.9.0__py3-none-any.whl → 1.10.0__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/a2a/__init__.py +73 -0
- t402/a2a/helpers.py +158 -0
- t402/a2a/types.py +145 -0
- t402/bridge/client.py +13 -5
- t402/bridge/constants.py +4 -2
- 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/django/__init__.py +42 -0
- t402/django/middleware.py +596 -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/errors.py +213 -0
- t402/evm_paywall_template.py +1 -1
- t402/facilitator.py +125 -0
- t402/fastapi/middleware.py +1 -3
- t402/mcp/constants.py +3 -6
- t402/mcp/server.py +501 -84
- t402/mcp/web3_utils.py +493 -0
- t402/multisig/__init__.py +120 -0
- t402/multisig/constants.py +54 -0
- t402/multisig/safe.py +441 -0
- t402/multisig/signature.py +228 -0
- t402/multisig/transaction.py +238 -0
- t402/multisig/types.py +108 -0
- t402/multisig/utils.py +77 -0
- t402/near_paywall_template.py +2 -0
- t402/networks.py +34 -1
- t402/paywall.py +1 -3
- t402/schemes/__init__.py +143 -0
- 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/cosmos/__init__.py +114 -0
- t402/schemes/cosmos/constants.py +211 -0
- t402/schemes/cosmos/exact_direct/__init__.py +21 -0
- t402/schemes/cosmos/exact_direct/client.py +198 -0
- t402/schemes/cosmos/exact_direct/facilitator.py +493 -0
- t402/schemes/cosmos/exact_direct/server.py +315 -0
- t402/schemes/cosmos/types.py +501 -0
- t402/schemes/evm/__init__.py +46 -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 +12 -0
- t402/schemes/evm/upto/client.py +6 -2
- t402/schemes/evm/upto/facilitator.py +625 -0
- t402/schemes/evm/upto/server.py +243 -0
- t402/schemes/evm/upto/types.py +3 -1
- t402/schemes/interfaces.py +6 -2
- t402/schemes/near/__init__.py +137 -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/near/upto/__init__.py +54 -0
- t402/schemes/near/upto/types.py +272 -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 +44 -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/svm/upto/__init__.py +23 -0
- t402/schemes/svm/upto/types.py +193 -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 +24 -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/ton/upto/__init__.py +31 -0
- t402/schemes/ton/upto/types.py +215 -0
- t402/schemes/tron/__init__.py +28 -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/tron/upto/__init__.py +30 -0
- t402/schemes/tron/upto/types.py +213 -0
- t402/stacks_paywall_template.py +2 -0
- t402/starlette/__init__.py +38 -0
- t402/starlette/middleware.py +522 -0
- t402/svm.py +45 -11
- t402/svm_paywall_template.py +1 -1
- t402/ton.py +6 -2
- t402/ton_paywall_template.py +1 -192
- t402/tron.py +2 -0
- t402/tron_paywall_template.py +2 -0
- t402/types.py +103 -3
- t402/wdk/chains.py +1 -1
- t402/wdk/errors.py +15 -5
- t402/wdk/signer.py +11 -2
- {t402-1.9.0.dist-info → t402-1.10.0.dist-info}/METADATA +42 -1
- t402-1.10.0.dist-info/RECORD +156 -0
- t402-1.9.0.dist-info/RECORD +0 -72
- {t402-1.9.0.dist-info → t402-1.10.0.dist-info}/WHEEL +0 -0
- {t402-1.9.0.dist-info → t402-1.10.0.dist-info}/entry_points.txt +0 -0
t402/schemes/ton/exact/server.py
CHANGED
|
@@ -99,7 +99,7 @@ class ExactTonServerScheme:
|
|
|
99
99
|
amount_decimal = Decimal(str(price))
|
|
100
100
|
|
|
101
101
|
# Convert to atomic units
|
|
102
|
-
atomic_amount = int(amount_decimal * Decimal(10
|
|
102
|
+
atomic_amount = int(amount_decimal * Decimal(10**decimals))
|
|
103
103
|
|
|
104
104
|
# Build extra metadata
|
|
105
105
|
extra = {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""TON Up-To Payment Scheme.
|
|
2
|
+
|
|
3
|
+
This package provides types for the upto payment scheme on TON blockchain.
|
|
4
|
+
|
|
5
|
+
The upto scheme uses an escrow pattern:
|
|
6
|
+
1. Client signs a transfer of maxAmount to the facilitator's holding address
|
|
7
|
+
2. Facilitator broadcasts the transfer, then sends settleAmount to payTo
|
|
8
|
+
and refunds (maxAmount - settleAmount) back to the client.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from t402.schemes.ton.upto.types import (
|
|
12
|
+
# Models
|
|
13
|
+
UptoTonAuthorization,
|
|
14
|
+
UptoTonPayload,
|
|
15
|
+
UptoTonExtra,
|
|
16
|
+
# Type guards
|
|
17
|
+
is_upto_ton_payload,
|
|
18
|
+
# Helper functions
|
|
19
|
+
upto_payload_from_dict,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
# Types
|
|
24
|
+
"UptoTonAuthorization",
|
|
25
|
+
"UptoTonPayload",
|
|
26
|
+
"UptoTonExtra",
|
|
27
|
+
# Type guards
|
|
28
|
+
"is_upto_ton_payload",
|
|
29
|
+
# Helper functions
|
|
30
|
+
"upto_payload_from_dict",
|
|
31
|
+
]
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""TON Up-To Scheme Types.
|
|
2
|
+
|
|
3
|
+
TON-specific types for the up-to payment scheme using an escrow pattern.
|
|
4
|
+
The client transfers maxAmount to the facilitator's holding address,
|
|
5
|
+
and the facilitator forwards settleAmount to payTo and refunds the rest.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, Optional
|
|
11
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
12
|
+
from pydantic.alias_generators import to_camel
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class UptoTonAuthorization(BaseModel):
|
|
16
|
+
"""TON upto authorization metadata.
|
|
17
|
+
|
|
18
|
+
Contains all parameters for verifying the signed transfer message.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from_address: str = Field(
|
|
22
|
+
alias="from",
|
|
23
|
+
description="Sender wallet address (friendly format, bounceable)",
|
|
24
|
+
)
|
|
25
|
+
facilitator: str = Field(
|
|
26
|
+
description="Facilitator holding address that receives the initial transfer",
|
|
27
|
+
)
|
|
28
|
+
jetton_master: str = Field(
|
|
29
|
+
alias="jettonMaster",
|
|
30
|
+
description="Jetton master contract address",
|
|
31
|
+
)
|
|
32
|
+
max_amount: str = Field(
|
|
33
|
+
alias="maxAmount",
|
|
34
|
+
description="Maximum authorized amount in smallest units",
|
|
35
|
+
)
|
|
36
|
+
ton_amount: str = Field(
|
|
37
|
+
alias="tonAmount",
|
|
38
|
+
description="Gas amount in nanoTON",
|
|
39
|
+
)
|
|
40
|
+
valid_until: int = Field(
|
|
41
|
+
alias="validUntil",
|
|
42
|
+
description="Unix timestamp (seconds) until which the message is valid",
|
|
43
|
+
)
|
|
44
|
+
seqno: int = Field(
|
|
45
|
+
description="Wallet sequence number for replay protection",
|
|
46
|
+
)
|
|
47
|
+
query_id: str = Field(
|
|
48
|
+
alias="queryId",
|
|
49
|
+
description="Unique message ID (as string for large numbers)",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
model_config = ConfigDict(
|
|
53
|
+
alias_generator=to_camel,
|
|
54
|
+
populate_by_name=True,
|
|
55
|
+
from_attributes=True,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class UptoTonPayload(BaseModel):
|
|
60
|
+
"""TON upto payment payload.
|
|
61
|
+
|
|
62
|
+
Contains a signed transfer message to the facilitator's holding address.
|
|
63
|
+
The facilitator broadcasts the transfer, then forwards settleAmount to payTo
|
|
64
|
+
and refunds (maxAmount - settleAmount) back to the client.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
signed_boc: str = Field(
|
|
68
|
+
alias="signedBoc",
|
|
69
|
+
description="Base64 encoded signed external message (BOC format)",
|
|
70
|
+
)
|
|
71
|
+
authorization: UptoTonAuthorization = Field(
|
|
72
|
+
description="Transfer authorization metadata for verification",
|
|
73
|
+
)
|
|
74
|
+
payment_nonce: str = Field(
|
|
75
|
+
alias="paymentNonce",
|
|
76
|
+
description="Unique nonce for replay protection (hex string)",
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
model_config = ConfigDict(
|
|
80
|
+
alias_generator=to_camel,
|
|
81
|
+
populate_by_name=True,
|
|
82
|
+
from_attributes=True,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
86
|
+
"""Convert to dictionary for JSON serialization.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Dictionary with camelCase keys matching the wire format.
|
|
90
|
+
"""
|
|
91
|
+
return {
|
|
92
|
+
"signedBoc": self.signed_boc,
|
|
93
|
+
"authorization": {
|
|
94
|
+
"from": self.authorization.from_address,
|
|
95
|
+
"facilitator": self.authorization.facilitator,
|
|
96
|
+
"jettonMaster": self.authorization.jetton_master,
|
|
97
|
+
"maxAmount": self.authorization.max_amount,
|
|
98
|
+
"tonAmount": self.authorization.ton_amount,
|
|
99
|
+
"validUntil": self.authorization.valid_until,
|
|
100
|
+
"seqno": self.authorization.seqno,
|
|
101
|
+
"queryId": self.authorization.query_id,
|
|
102
|
+
},
|
|
103
|
+
"paymentNonce": self.payment_nonce,
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class UptoTonExtra(BaseModel):
|
|
108
|
+
"""TON-specific extra fields for the upto scheme.
|
|
109
|
+
|
|
110
|
+
Included in PaymentRequirements.extra to provide upto-specific parameters.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
facilitator: Optional[str] = Field(
|
|
114
|
+
default=None,
|
|
115
|
+
description="Facilitator address that will receive the initial transfer",
|
|
116
|
+
)
|
|
117
|
+
max_amount: Optional[str] = Field(
|
|
118
|
+
default=None,
|
|
119
|
+
alias="maxAmount",
|
|
120
|
+
description="Maximum payment amount authorized",
|
|
121
|
+
)
|
|
122
|
+
min_amount: Optional[str] = Field(
|
|
123
|
+
default=None,
|
|
124
|
+
alias="minAmount",
|
|
125
|
+
description="Minimum acceptable settlement amount",
|
|
126
|
+
)
|
|
127
|
+
unit: Optional[str] = Field(
|
|
128
|
+
default=None,
|
|
129
|
+
description="Billing unit (e.g., 'token', 'request', 'second')",
|
|
130
|
+
)
|
|
131
|
+
unit_price: Optional[str] = Field(
|
|
132
|
+
default=None,
|
|
133
|
+
alias="unitPrice",
|
|
134
|
+
description="Price per unit in smallest denomination",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
model_config = ConfigDict(
|
|
138
|
+
alias_generator=to_camel,
|
|
139
|
+
populate_by_name=True,
|
|
140
|
+
from_attributes=True,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def is_upto_ton_payload(data: Any) -> bool:
|
|
145
|
+
"""Check if the given data represents a TON upto payload.
|
|
146
|
+
|
|
147
|
+
Validates the presence and types of required fields including signedBoc,
|
|
148
|
+
authorization (with from, facilitator, jettonMaster, maxAmount), and paymentNonce.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
data: Dictionary or object to check.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
True if data has the correct TON upto payload structure.
|
|
155
|
+
"""
|
|
156
|
+
if not isinstance(data, dict):
|
|
157
|
+
return False
|
|
158
|
+
|
|
159
|
+
signed_boc = data.get("signedBoc")
|
|
160
|
+
payment_nonce = data.get("paymentNonce")
|
|
161
|
+
auth = data.get("authorization")
|
|
162
|
+
|
|
163
|
+
if not signed_boc or not isinstance(signed_boc, str):
|
|
164
|
+
return False
|
|
165
|
+
if not payment_nonce or not isinstance(payment_nonce, str):
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
if not auth or not isinstance(auth, dict):
|
|
169
|
+
return False
|
|
170
|
+
|
|
171
|
+
# Check required authorization fields
|
|
172
|
+
required_str_fields = ["from", "facilitator", "jettonMaster", "maxAmount", "tonAmount", "queryId"]
|
|
173
|
+
for field in required_str_fields:
|
|
174
|
+
val = auth.get(field)
|
|
175
|
+
if not isinstance(val, str):
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
# from and facilitator must not be empty
|
|
179
|
+
if not auth.get("from") or not auth.get("facilitator"):
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
# Check numeric fields
|
|
183
|
+
if not isinstance(auth.get("validUntil"), (int, float)):
|
|
184
|
+
return False
|
|
185
|
+
if not isinstance(auth.get("seqno"), (int, float)):
|
|
186
|
+
return False
|
|
187
|
+
|
|
188
|
+
return True
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def upto_payload_from_dict(data: Dict[str, Any]) -> UptoTonPayload:
|
|
192
|
+
"""Create an UptoTonPayload from a dictionary.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
data: Dictionary containing payload data with camelCase keys.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
UptoTonPayload instance.
|
|
199
|
+
"""
|
|
200
|
+
auth_data = data.get("authorization", {})
|
|
201
|
+
|
|
202
|
+
return UptoTonPayload(
|
|
203
|
+
signed_boc=data.get("signedBoc", ""),
|
|
204
|
+
authorization=UptoTonAuthorization(
|
|
205
|
+
from_address=auth_data.get("from", ""),
|
|
206
|
+
facilitator=auth_data.get("facilitator", ""),
|
|
207
|
+
jetton_master=auth_data.get("jettonMaster", ""),
|
|
208
|
+
max_amount=auth_data.get("maxAmount", ""),
|
|
209
|
+
ton_amount=auth_data.get("tonAmount", ""),
|
|
210
|
+
valid_until=auth_data.get("validUntil", 0),
|
|
211
|
+
seqno=auth_data.get("seqno", 0),
|
|
212
|
+
query_id=auth_data.get("queryId", ""),
|
|
213
|
+
),
|
|
214
|
+
payment_nonce=data.get("paymentNonce", ""),
|
|
215
|
+
)
|
t402/schemes/tron/__init__.py
CHANGED
|
@@ -4,19 +4,45 @@ This package provides payment scheme implementations for TRON blockchain.
|
|
|
4
4
|
|
|
5
5
|
Supported schemes:
|
|
6
6
|
- exact: TRC-20 token transfers with signed transactions
|
|
7
|
+
- upto: TRC-20 approve + transferFrom for authorized maximum-amount payments
|
|
7
8
|
"""
|
|
8
9
|
|
|
9
10
|
from t402.schemes.tron.exact import (
|
|
10
11
|
ExactTronClientScheme,
|
|
11
12
|
ExactTronServerScheme,
|
|
13
|
+
ExactTronFacilitatorScheme,
|
|
14
|
+
ExactTronFacilitatorConfig,
|
|
12
15
|
TronSigner,
|
|
16
|
+
FacilitatorTronSigner,
|
|
13
17
|
SCHEME_EXACT,
|
|
14
18
|
)
|
|
15
19
|
|
|
20
|
+
from t402.schemes.tron.upto import (
|
|
21
|
+
UptoTronAuthorization,
|
|
22
|
+
UptoTronPayload,
|
|
23
|
+
UptoTronExtra,
|
|
24
|
+
is_upto_tron_payload,
|
|
25
|
+
upto_payload_from_dict,
|
|
26
|
+
)
|
|
27
|
+
|
|
16
28
|
__all__ = [
|
|
17
|
-
# Exact
|
|
29
|
+
# Exact - Client
|
|
18
30
|
"ExactTronClientScheme",
|
|
19
|
-
"ExactTronServerScheme",
|
|
20
31
|
"TronSigner",
|
|
32
|
+
# Exact - Server
|
|
33
|
+
"ExactTronServerScheme",
|
|
34
|
+
# Exact - Facilitator
|
|
35
|
+
"ExactTronFacilitatorScheme",
|
|
36
|
+
"ExactTronFacilitatorConfig",
|
|
37
|
+
"FacilitatorTronSigner",
|
|
38
|
+
# Exact - Constants
|
|
21
39
|
"SCHEME_EXACT",
|
|
40
|
+
# Upto - Types
|
|
41
|
+
"UptoTronAuthorization",
|
|
42
|
+
"UptoTronPayload",
|
|
43
|
+
"UptoTronExtra",
|
|
44
|
+
# Upto - Type guards
|
|
45
|
+
"is_upto_tron_payload",
|
|
46
|
+
# Upto - Helpers
|
|
47
|
+
"upto_payload_from_dict",
|
|
22
48
|
]
|
|
@@ -15,6 +15,11 @@ from t402.schemes.tron.exact.client import (
|
|
|
15
15
|
from t402.schemes.tron.exact.server import (
|
|
16
16
|
ExactTronServerScheme,
|
|
17
17
|
)
|
|
18
|
+
from t402.schemes.tron.exact.facilitator import (
|
|
19
|
+
ExactTronFacilitatorScheme,
|
|
20
|
+
ExactTronFacilitatorConfig,
|
|
21
|
+
FacilitatorTronSigner,
|
|
22
|
+
)
|
|
18
23
|
|
|
19
24
|
__all__ = [
|
|
20
25
|
# Client
|
|
@@ -22,6 +27,10 @@ __all__ = [
|
|
|
22
27
|
"TronSigner",
|
|
23
28
|
# Server
|
|
24
29
|
"ExactTronServerScheme",
|
|
30
|
+
# Facilitator
|
|
31
|
+
"ExactTronFacilitatorScheme",
|
|
32
|
+
"ExactTronFacilitatorConfig",
|
|
33
|
+
"FacilitatorTronSigner",
|
|
25
34
|
# Constants
|
|
26
35
|
"SCHEME_EXACT",
|
|
27
36
|
]
|