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/networks.py
CHANGED
|
@@ -2,7 +2,16 @@ from typing import Literal, Union, get_args
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
# EVM Networks
|
|
5
|
-
EVMNetworks = Literal[
|
|
5
|
+
EVMNetworks = Literal[
|
|
6
|
+
# Standard networks
|
|
7
|
+
"base", "base-sepolia", "avalanche-fuji", "avalanche",
|
|
8
|
+
# Core USDT0 Networks
|
|
9
|
+
"ethereum", "arbitrum", "optimism", "polygon", "ink", "berachain", "unichain",
|
|
10
|
+
# Phase 1: High Priority USDT0 Networks
|
|
11
|
+
"mantle", "plasma", "sei", "conflux", "monad",
|
|
12
|
+
# Phase 2: Medium Priority USDT0 Networks
|
|
13
|
+
"flare", "rootstock", "xlayer", "stable", "hyperevm", "megaeth", "corn",
|
|
14
|
+
]
|
|
6
15
|
|
|
7
16
|
# TON Networks (CAIP-2 format)
|
|
8
17
|
TONNetworks = Literal["ton:mainnet", "ton:testnet"]
|
|
@@ -32,11 +41,35 @@ def get_all_supported_networks() -> tuple[str, ...]:
|
|
|
32
41
|
svm = get_args(SVMNetworks)
|
|
33
42
|
return evm + ton + tron + svm
|
|
34
43
|
|
|
44
|
+
|
|
35
45
|
EVM_NETWORK_TO_CHAIN_ID = {
|
|
46
|
+
# Standard networks
|
|
36
47
|
"base-sepolia": 84532,
|
|
37
48
|
"base": 8453,
|
|
38
49
|
"avalanche-fuji": 43113,
|
|
39
50
|
"avalanche": 43114,
|
|
51
|
+
# Core USDT0 Networks
|
|
52
|
+
"ethereum": 1,
|
|
53
|
+
"arbitrum": 42161,
|
|
54
|
+
"optimism": 10,
|
|
55
|
+
"polygon": 137,
|
|
56
|
+
"ink": 57073,
|
|
57
|
+
"berachain": 80094,
|
|
58
|
+
"unichain": 130,
|
|
59
|
+
# Phase 1: High Priority USDT0 Networks
|
|
60
|
+
"mantle": 5000,
|
|
61
|
+
"plasma": 9745,
|
|
62
|
+
"sei": 1329,
|
|
63
|
+
"conflux": 1030,
|
|
64
|
+
"monad": 143,
|
|
65
|
+
# Phase 2: Medium Priority USDT0 Networks
|
|
66
|
+
"flare": 14,
|
|
67
|
+
"rootstock": 30,
|
|
68
|
+
"xlayer": 196,
|
|
69
|
+
"stable": 988,
|
|
70
|
+
"hyperevm": 999,
|
|
71
|
+
"megaeth": 4326,
|
|
72
|
+
"corn": 21000000,
|
|
40
73
|
}
|
|
41
74
|
|
|
42
75
|
# TON Network configurations
|
t402/paywall.py
CHANGED
|
@@ -127,6 +127,4 @@ def get_paywall_html(
|
|
|
127
127
|
raise ValueError("payment_requirements cannot be empty")
|
|
128
128
|
network = payment_requirements[0].network
|
|
129
129
|
template = get_paywall_template(network)
|
|
130
|
-
return inject_payment_data(
|
|
131
|
-
template, error, payment_requirements, paywall_config
|
|
132
|
-
)
|
|
130
|
+
return inject_payment_data(template, error, payment_requirements, paywall_config)
|
t402/schemes/__init__.py
CHANGED
|
@@ -70,9 +70,15 @@ from t402.schemes.registry import (
|
|
|
70
70
|
from t402.schemes.evm import (
|
|
71
71
|
ExactEvmClientScheme,
|
|
72
72
|
ExactEvmServerScheme,
|
|
73
|
+
ExactEvmFacilitatorScheme,
|
|
74
|
+
FacilitatorEvmSigner,
|
|
75
|
+
EvmVerifyResult,
|
|
76
|
+
EvmTransactionConfirmation,
|
|
73
77
|
EvmSigner,
|
|
74
78
|
# Upto EVM
|
|
75
79
|
UptoEvmClientScheme,
|
|
80
|
+
UptoEvmServerScheme,
|
|
81
|
+
UptoEvmFacilitatorScheme,
|
|
76
82
|
PermitSignature,
|
|
77
83
|
PermitAuthorization,
|
|
78
84
|
UptoEIP2612Payload,
|
|
@@ -98,14 +104,90 @@ from t402.schemes.upto import (
|
|
|
98
104
|
from t402.schemes.ton import (
|
|
99
105
|
ExactTonClientScheme,
|
|
100
106
|
ExactTonServerScheme,
|
|
107
|
+
ExactTonFacilitatorScheme,
|
|
101
108
|
TonSigner,
|
|
109
|
+
FacilitatorTonSigner,
|
|
102
110
|
)
|
|
103
111
|
|
|
104
112
|
# TRON Schemes
|
|
105
113
|
from t402.schemes.tron import (
|
|
106
114
|
ExactTronClientScheme,
|
|
107
115
|
ExactTronServerScheme,
|
|
116
|
+
ExactTronFacilitatorScheme,
|
|
117
|
+
ExactTronFacilitatorConfig,
|
|
108
118
|
TronSigner,
|
|
119
|
+
FacilitatorTronSigner,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# SVM Schemes
|
|
123
|
+
from t402.schemes.svm import (
|
|
124
|
+
ExactSvmClientScheme,
|
|
125
|
+
ExactSvmServerScheme,
|
|
126
|
+
ExactSvmFacilitatorScheme,
|
|
127
|
+
ClientSvmSigner as SvmClientSigner,
|
|
128
|
+
FacilitatorSvmSigner as SvmFacilitatorSigner,
|
|
129
|
+
SCHEME_EXACT as SVM_SCHEME_EXACT,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# NEAR Schemes
|
|
133
|
+
from t402.schemes.near import (
|
|
134
|
+
ExactDirectNearClientScheme,
|
|
135
|
+
ExactDirectNearServerScheme,
|
|
136
|
+
ExactDirectNearFacilitatorScheme,
|
|
137
|
+
ClientNearSigner,
|
|
138
|
+
FacilitatorNearSigner,
|
|
139
|
+
SCHEME_EXACT_DIRECT as NEAR_SCHEME_EXACT_DIRECT,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# Aptos Schemes
|
|
143
|
+
from t402.schemes.aptos import (
|
|
144
|
+
ExactDirectAptosClientScheme,
|
|
145
|
+
ExactDirectAptosServerScheme,
|
|
146
|
+
ExactDirectAptosFacilitatorScheme,
|
|
147
|
+
ClientAptosSigner,
|
|
148
|
+
FacilitatorAptosSigner,
|
|
149
|
+
SCHEME_EXACT_DIRECT,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# Polkadot Schemes
|
|
153
|
+
from t402.schemes.polkadot import (
|
|
154
|
+
ExactDirectPolkadotClientScheme,
|
|
155
|
+
ExactDirectPolkadotServerScheme,
|
|
156
|
+
ExactDirectPolkadotFacilitatorScheme,
|
|
157
|
+
ClientPolkadotSigner,
|
|
158
|
+
FacilitatorPolkadotSigner,
|
|
159
|
+
SCHEME_EXACT_DIRECT as POLKADOT_SCHEME_EXACT_DIRECT,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Tezos Schemes
|
|
163
|
+
from t402.schemes.tezos import (
|
|
164
|
+
ExactDirectTezosClient,
|
|
165
|
+
ExactDirectTezosServer,
|
|
166
|
+
ExactDirectTezosFacilitator,
|
|
167
|
+
ClientTezosSigner,
|
|
168
|
+
FacilitatorTezosSigner,
|
|
169
|
+
SCHEME_EXACT_DIRECT as TEZOS_SCHEME_EXACT_DIRECT,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
# Stacks Schemes
|
|
173
|
+
from t402.schemes.stacks import (
|
|
174
|
+
ExactDirectStacksClientScheme,
|
|
175
|
+
ExactDirectStacksServerScheme,
|
|
176
|
+
ExactDirectStacksFacilitatorScheme,
|
|
177
|
+
ClientStacksSigner,
|
|
178
|
+
FacilitatorStacksSigner,
|
|
179
|
+
SCHEME_EXACT_DIRECT as STACKS_SCHEME_EXACT_DIRECT,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
# Cosmos Schemes
|
|
183
|
+
from t402.schemes.cosmos import (
|
|
184
|
+
ExactDirectCosmosClientScheme,
|
|
185
|
+
ExactDirectCosmosServerScheme,
|
|
186
|
+
ExactDirectCosmosFacilitatorScheme,
|
|
187
|
+
ExactDirectCosmosFacilitatorConfig,
|
|
188
|
+
ClientCosmosSigner,
|
|
189
|
+
FacilitatorCosmosSigner,
|
|
190
|
+
SCHEME_EXACT_DIRECT as COSMOS_SCHEME_EXACT_DIRECT,
|
|
109
191
|
)
|
|
110
192
|
|
|
111
193
|
__all__ = [
|
|
@@ -134,9 +216,15 @@ __all__ = [
|
|
|
134
216
|
# EVM Exact Schemes
|
|
135
217
|
"ExactEvmClientScheme",
|
|
136
218
|
"ExactEvmServerScheme",
|
|
219
|
+
"ExactEvmFacilitatorScheme",
|
|
220
|
+
"FacilitatorEvmSigner",
|
|
221
|
+
"EvmVerifyResult",
|
|
222
|
+
"EvmTransactionConfirmation",
|
|
137
223
|
"EvmSigner",
|
|
138
224
|
# EVM Upto Schemes
|
|
139
225
|
"UptoEvmClientScheme",
|
|
226
|
+
"UptoEvmServerScheme",
|
|
227
|
+
"UptoEvmFacilitatorScheme",
|
|
140
228
|
"PermitSignature",
|
|
141
229
|
"PermitAuthorization",
|
|
142
230
|
"UptoEIP2612Payload",
|
|
@@ -156,9 +244,64 @@ __all__ = [
|
|
|
156
244
|
# TON Schemes
|
|
157
245
|
"ExactTonClientScheme",
|
|
158
246
|
"ExactTonServerScheme",
|
|
247
|
+
"ExactTonFacilitatorScheme",
|
|
159
248
|
"TonSigner",
|
|
249
|
+
"FacilitatorTonSigner",
|
|
160
250
|
# TRON Schemes
|
|
161
251
|
"ExactTronClientScheme",
|
|
162
252
|
"ExactTronServerScheme",
|
|
253
|
+
"ExactTronFacilitatorScheme",
|
|
254
|
+
"ExactTronFacilitatorConfig",
|
|
163
255
|
"TronSigner",
|
|
256
|
+
"FacilitatorTronSigner",
|
|
257
|
+
# SVM Schemes
|
|
258
|
+
"ExactSvmClientScheme",
|
|
259
|
+
"ExactSvmServerScheme",
|
|
260
|
+
"ExactSvmFacilitatorScheme",
|
|
261
|
+
"SvmClientSigner",
|
|
262
|
+
"SvmFacilitatorSigner",
|
|
263
|
+
"SVM_SCHEME_EXACT",
|
|
264
|
+
# NEAR Schemes
|
|
265
|
+
"ExactDirectNearClientScheme",
|
|
266
|
+
"ExactDirectNearServerScheme",
|
|
267
|
+
"ExactDirectNearFacilitatorScheme",
|
|
268
|
+
"ClientNearSigner",
|
|
269
|
+
"FacilitatorNearSigner",
|
|
270
|
+
"NEAR_SCHEME_EXACT_DIRECT",
|
|
271
|
+
# Aptos Schemes
|
|
272
|
+
"ExactDirectAptosClientScheme",
|
|
273
|
+
"ExactDirectAptosServerScheme",
|
|
274
|
+
"ExactDirectAptosFacilitatorScheme",
|
|
275
|
+
"ClientAptosSigner",
|
|
276
|
+
"FacilitatorAptosSigner",
|
|
277
|
+
"SCHEME_EXACT_DIRECT",
|
|
278
|
+
# Polkadot Schemes
|
|
279
|
+
"ExactDirectPolkadotClientScheme",
|
|
280
|
+
"ExactDirectPolkadotServerScheme",
|
|
281
|
+
"ExactDirectPolkadotFacilitatorScheme",
|
|
282
|
+
"ClientPolkadotSigner",
|
|
283
|
+
"FacilitatorPolkadotSigner",
|
|
284
|
+
"POLKADOT_SCHEME_EXACT_DIRECT",
|
|
285
|
+
# Tezos Schemes
|
|
286
|
+
"ExactDirectTezosClient",
|
|
287
|
+
"ExactDirectTezosServer",
|
|
288
|
+
"ExactDirectTezosFacilitator",
|
|
289
|
+
"ClientTezosSigner",
|
|
290
|
+
"FacilitatorTezosSigner",
|
|
291
|
+
"TEZOS_SCHEME_EXACT_DIRECT",
|
|
292
|
+
# Stacks Schemes
|
|
293
|
+
"ExactDirectStacksClientScheme",
|
|
294
|
+
"ExactDirectStacksServerScheme",
|
|
295
|
+
"ExactDirectStacksFacilitatorScheme",
|
|
296
|
+
"ClientStacksSigner",
|
|
297
|
+
"FacilitatorStacksSigner",
|
|
298
|
+
"STACKS_SCHEME_EXACT_DIRECT",
|
|
299
|
+
# Cosmos Schemes
|
|
300
|
+
"ExactDirectCosmosClientScheme",
|
|
301
|
+
"ExactDirectCosmosServerScheme",
|
|
302
|
+
"ExactDirectCosmosFacilitatorScheme",
|
|
303
|
+
"ExactDirectCosmosFacilitatorConfig",
|
|
304
|
+
"ClientCosmosSigner",
|
|
305
|
+
"FacilitatorCosmosSigner",
|
|
306
|
+
"COSMOS_SCHEME_EXACT_DIRECT",
|
|
164
307
|
]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Aptos Blockchain Payment Schemes.
|
|
2
|
+
|
|
3
|
+
This package provides payment scheme implementations for the Aptos blockchain.
|
|
4
|
+
|
|
5
|
+
Supported schemes:
|
|
6
|
+
- exact-direct: Fungible Asset transfers via 0x1::primary_fungible_store::transfer
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from t402.schemes.aptos.exact_direct import (
|
|
10
|
+
ExactDirectAptosClientScheme,
|
|
11
|
+
ExactDirectAptosServerScheme,
|
|
12
|
+
ExactDirectAptosFacilitatorScheme,
|
|
13
|
+
ClientAptosSigner,
|
|
14
|
+
FacilitatorAptosSigner,
|
|
15
|
+
ExactDirectPayload,
|
|
16
|
+
SCHEME_EXACT_DIRECT,
|
|
17
|
+
)
|
|
18
|
+
from t402.schemes.aptos.constants import (
|
|
19
|
+
APTOS_MAINNET,
|
|
20
|
+
APTOS_TESTNET,
|
|
21
|
+
APTOS_DEVNET,
|
|
22
|
+
CAIP_FAMILY,
|
|
23
|
+
USDT_MAINNET_METADATA,
|
|
24
|
+
USDC_MAINNET_METADATA,
|
|
25
|
+
FA_TRANSFER_FUNCTION,
|
|
26
|
+
DEFAULT_DECIMALS,
|
|
27
|
+
is_valid_address,
|
|
28
|
+
is_valid_tx_hash,
|
|
29
|
+
is_valid_network,
|
|
30
|
+
compare_addresses,
|
|
31
|
+
normalize_address,
|
|
32
|
+
parse_amount,
|
|
33
|
+
format_amount,
|
|
34
|
+
get_network_config,
|
|
35
|
+
get_token_info,
|
|
36
|
+
get_token_by_address,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
# Exact-Direct scheme
|
|
41
|
+
"ExactDirectAptosClientScheme",
|
|
42
|
+
"ExactDirectAptosServerScheme",
|
|
43
|
+
"ExactDirectAptosFacilitatorScheme",
|
|
44
|
+
# Signer protocols
|
|
45
|
+
"ClientAptosSigner",
|
|
46
|
+
"FacilitatorAptosSigner",
|
|
47
|
+
# Types
|
|
48
|
+
"ExactDirectPayload",
|
|
49
|
+
# Constants
|
|
50
|
+
"SCHEME_EXACT_DIRECT",
|
|
51
|
+
"APTOS_MAINNET",
|
|
52
|
+
"APTOS_TESTNET",
|
|
53
|
+
"APTOS_DEVNET",
|
|
54
|
+
"CAIP_FAMILY",
|
|
55
|
+
"USDT_MAINNET_METADATA",
|
|
56
|
+
"USDC_MAINNET_METADATA",
|
|
57
|
+
"FA_TRANSFER_FUNCTION",
|
|
58
|
+
"DEFAULT_DECIMALS",
|
|
59
|
+
# Utility functions
|
|
60
|
+
"is_valid_address",
|
|
61
|
+
"is_valid_tx_hash",
|
|
62
|
+
"is_valid_network",
|
|
63
|
+
"compare_addresses",
|
|
64
|
+
"normalize_address",
|
|
65
|
+
"parse_amount",
|
|
66
|
+
"format_amount",
|
|
67
|
+
"get_network_config",
|
|
68
|
+
"get_token_info",
|
|
69
|
+
"get_token_by_address",
|
|
70
|
+
]
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"""Aptos Network Constants and Token Registry.
|
|
2
|
+
|
|
3
|
+
This module defines constants for Aptos blockchain networks, token metadata
|
|
4
|
+
addresses, and network configurations used by the exact-direct payment scheme.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any, Dict, Optional
|
|
10
|
+
|
|
11
|
+
# Scheme identifier
|
|
12
|
+
SCHEME_EXACT_DIRECT = "exact-direct"
|
|
13
|
+
|
|
14
|
+
# CAIP-2 family pattern
|
|
15
|
+
CAIP_FAMILY = "aptos:*"
|
|
16
|
+
|
|
17
|
+
# CAIP-2 network identifiers
|
|
18
|
+
APTOS_MAINNET = "aptos:1"
|
|
19
|
+
APTOS_TESTNET = "aptos:2"
|
|
20
|
+
APTOS_DEVNET = "aptos:149"
|
|
21
|
+
|
|
22
|
+
# RPC endpoints
|
|
23
|
+
APTOS_MAINNET_RPC = "https://fullnode.mainnet.aptoslabs.com/v1"
|
|
24
|
+
APTOS_TESTNET_RPC = "https://fullnode.testnet.aptoslabs.com/v1"
|
|
25
|
+
APTOS_DEVNET_RPC = "https://fullnode.devnet.aptoslabs.com/v1"
|
|
26
|
+
|
|
27
|
+
# Fungible Asset transfer function
|
|
28
|
+
FA_TRANSFER_FUNCTION = "0x1::primary_fungible_store::transfer"
|
|
29
|
+
|
|
30
|
+
# Default decimals for USDT on Aptos
|
|
31
|
+
DEFAULT_DECIMALS = 6
|
|
32
|
+
|
|
33
|
+
# USDT Fungible Asset metadata address on Aptos mainnet
|
|
34
|
+
USDT_MAINNET_METADATA = (
|
|
35
|
+
"0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# USDC metadata address on Aptos mainnet
|
|
39
|
+
USDC_MAINNET_METADATA = (
|
|
40
|
+
"0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b"
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Token information structure
|
|
45
|
+
class TokenInfo:
|
|
46
|
+
"""Contains information about an Aptos fungible asset.
|
|
47
|
+
|
|
48
|
+
Attributes:
|
|
49
|
+
metadata_address: The on-chain FA metadata object address.
|
|
50
|
+
symbol: Token ticker symbol (e.g., "USDT").
|
|
51
|
+
name: Human-readable token name (e.g., "Tether USD").
|
|
52
|
+
decimals: Number of decimal places for the token.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
metadata_address: str,
|
|
58
|
+
symbol: str,
|
|
59
|
+
name: str,
|
|
60
|
+
decimals: int,
|
|
61
|
+
) -> None:
|
|
62
|
+
self.metadata_address = metadata_address
|
|
63
|
+
self.symbol = symbol
|
|
64
|
+
self.name = name
|
|
65
|
+
self.decimals = decimals
|
|
66
|
+
|
|
67
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
68
|
+
"""Convert to dictionary representation."""
|
|
69
|
+
return {
|
|
70
|
+
"metadata_address": self.metadata_address,
|
|
71
|
+
"symbol": self.symbol,
|
|
72
|
+
"name": self.name,
|
|
73
|
+
"decimals": self.decimals,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# Token definitions
|
|
78
|
+
USDT_MAINNET = TokenInfo(
|
|
79
|
+
metadata_address=USDT_MAINNET_METADATA,
|
|
80
|
+
symbol="USDT",
|
|
81
|
+
name="Tether USD",
|
|
82
|
+
decimals=6,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
USDC_MAINNET = TokenInfo(
|
|
86
|
+
metadata_address=USDC_MAINNET_METADATA,
|
|
87
|
+
symbol="USDC",
|
|
88
|
+
name="USD Coin",
|
|
89
|
+
decimals=6,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# Network configuration
|
|
94
|
+
class NetworkConfig:
|
|
95
|
+
"""Network-specific configuration for Aptos.
|
|
96
|
+
|
|
97
|
+
Attributes:
|
|
98
|
+
chain_id: Numeric chain ID.
|
|
99
|
+
rpc_url: Default RPC endpoint URL.
|
|
100
|
+
default_token: Default token for this network.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self,
|
|
105
|
+
chain_id: int,
|
|
106
|
+
rpc_url: str,
|
|
107
|
+
default_token: TokenInfo,
|
|
108
|
+
) -> None:
|
|
109
|
+
self.chain_id = chain_id
|
|
110
|
+
self.rpc_url = rpc_url
|
|
111
|
+
self.default_token = default_token
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# Network configurations registry
|
|
115
|
+
NETWORK_CONFIGS: Dict[str, NetworkConfig] = {
|
|
116
|
+
APTOS_MAINNET: NetworkConfig(
|
|
117
|
+
chain_id=1,
|
|
118
|
+
rpc_url=APTOS_MAINNET_RPC,
|
|
119
|
+
default_token=USDT_MAINNET,
|
|
120
|
+
),
|
|
121
|
+
APTOS_TESTNET: NetworkConfig(
|
|
122
|
+
chain_id=2,
|
|
123
|
+
rpc_url=APTOS_TESTNET_RPC,
|
|
124
|
+
default_token=USDT_MAINNET,
|
|
125
|
+
),
|
|
126
|
+
APTOS_DEVNET: NetworkConfig(
|
|
127
|
+
chain_id=149,
|
|
128
|
+
rpc_url=APTOS_DEVNET_RPC,
|
|
129
|
+
default_token=USDT_MAINNET,
|
|
130
|
+
),
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
# Token registry by network
|
|
134
|
+
TOKEN_REGISTRY: Dict[str, Dict[str, TokenInfo]] = {
|
|
135
|
+
APTOS_MAINNET: {
|
|
136
|
+
"USDT": USDT_MAINNET,
|
|
137
|
+
"USDC": USDC_MAINNET,
|
|
138
|
+
},
|
|
139
|
+
APTOS_TESTNET: {
|
|
140
|
+
"USDT": USDT_MAINNET,
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def get_network_config(network: str) -> Optional[NetworkConfig]:
|
|
146
|
+
"""Get the configuration for a given network.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
network: CAIP-2 network identifier (e.g., "aptos:1").
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
NetworkConfig if found, None otherwise.
|
|
153
|
+
"""
|
|
154
|
+
return NETWORK_CONFIGS.get(network)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_token_info(network: str, symbol: str) -> Optional[TokenInfo]:
|
|
158
|
+
"""Get token info for a network and symbol.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
network: CAIP-2 network identifier.
|
|
162
|
+
symbol: Token symbol (e.g., "USDT").
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
TokenInfo if found, None otherwise.
|
|
166
|
+
"""
|
|
167
|
+
tokens = TOKEN_REGISTRY.get(network)
|
|
168
|
+
if not tokens:
|
|
169
|
+
return None
|
|
170
|
+
return tokens.get(symbol)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def get_token_by_address(network: str, metadata_address: str) -> Optional[TokenInfo]:
|
|
174
|
+
"""Get token info by FA metadata address.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
network: CAIP-2 network identifier.
|
|
178
|
+
metadata_address: The on-chain metadata object address.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
TokenInfo if found, None otherwise.
|
|
182
|
+
"""
|
|
183
|
+
tokens = TOKEN_REGISTRY.get(network)
|
|
184
|
+
if not tokens:
|
|
185
|
+
return None
|
|
186
|
+
normalized = normalize_address(metadata_address)
|
|
187
|
+
for token in tokens.values():
|
|
188
|
+
if normalize_address(token.metadata_address) == normalized:
|
|
189
|
+
return token
|
|
190
|
+
return None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def is_valid_network(network: str) -> bool:
|
|
194
|
+
"""Check if a network identifier is supported.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
network: CAIP-2 network identifier.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
True if the network is known and supported.
|
|
201
|
+
"""
|
|
202
|
+
return network in NETWORK_CONFIGS
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def is_valid_address(address: str) -> bool:
|
|
206
|
+
"""Validate an Aptos address format.
|
|
207
|
+
|
|
208
|
+
Aptos addresses are 0x-prefixed hex strings, up to 64 hex characters.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
address: The address to validate.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
True if the address is valid.
|
|
215
|
+
"""
|
|
216
|
+
if not address:
|
|
217
|
+
return False
|
|
218
|
+
if not address.startswith("0x"):
|
|
219
|
+
return False
|
|
220
|
+
hex_part = address[2:]
|
|
221
|
+
if len(hex_part) == 0 or len(hex_part) > 64:
|
|
222
|
+
return False
|
|
223
|
+
try:
|
|
224
|
+
int(hex_part, 16)
|
|
225
|
+
return True
|
|
226
|
+
except ValueError:
|
|
227
|
+
return False
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def is_valid_tx_hash(tx_hash: str) -> bool:
|
|
231
|
+
"""Validate an Aptos transaction hash format.
|
|
232
|
+
|
|
233
|
+
Transaction hashes are 0x-prefixed hex strings of exactly 64 hex characters.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
tx_hash: The transaction hash to validate.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
True if the hash is valid.
|
|
240
|
+
"""
|
|
241
|
+
if not tx_hash:
|
|
242
|
+
return False
|
|
243
|
+
if not tx_hash.startswith("0x"):
|
|
244
|
+
return False
|
|
245
|
+
hex_part = tx_hash[2:]
|
|
246
|
+
if len(hex_part) != 64:
|
|
247
|
+
return False
|
|
248
|
+
try:
|
|
249
|
+
int(hex_part, 16)
|
|
250
|
+
return True
|
|
251
|
+
except ValueError:
|
|
252
|
+
return False
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def normalize_address(address: str) -> str:
|
|
256
|
+
"""Normalize an Aptos address for comparison.
|
|
257
|
+
|
|
258
|
+
Converts to lowercase and ensures 0x prefix.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
address: The address to normalize.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
Normalized address string.
|
|
265
|
+
"""
|
|
266
|
+
if not address:
|
|
267
|
+
return ""
|
|
268
|
+
if address.startswith("0x"):
|
|
269
|
+
return "0x" + address[2:].lower()
|
|
270
|
+
return "0x" + address.lower()
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def compare_addresses(addr1: str, addr2: str) -> bool:
|
|
274
|
+
"""Compare two Aptos addresses (case-insensitive).
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
addr1: First address.
|
|
278
|
+
addr2: Second address.
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
True if addresses are equivalent.
|
|
282
|
+
"""
|
|
283
|
+
if not addr1 or not addr2:
|
|
284
|
+
return False
|
|
285
|
+
return normalize_address(addr1) == normalize_address(addr2)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def parse_amount(amount: str, decimals: int) -> int:
|
|
289
|
+
"""Convert a decimal string amount to atomic units.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
amount: Decimal amount string (e.g., "1.5").
|
|
293
|
+
decimals: Number of decimal places for the token.
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
Amount in smallest atomic units.
|
|
297
|
+
|
|
298
|
+
Raises:
|
|
299
|
+
ValueError: If the amount format is invalid.
|
|
300
|
+
"""
|
|
301
|
+
amount = amount.strip()
|
|
302
|
+
parts = amount.split(".")
|
|
303
|
+
|
|
304
|
+
if len(parts) > 2:
|
|
305
|
+
raise ValueError(f"Invalid amount format: {amount}")
|
|
306
|
+
|
|
307
|
+
try:
|
|
308
|
+
int_part = int(parts[0])
|
|
309
|
+
except ValueError:
|
|
310
|
+
raise ValueError(f"Invalid integer part: {parts[0]}")
|
|
311
|
+
|
|
312
|
+
dec_part = 0
|
|
313
|
+
if len(parts) == 2 and parts[1]:
|
|
314
|
+
dec_str = parts[1]
|
|
315
|
+
if len(dec_str) > decimals:
|
|
316
|
+
dec_str = dec_str[:decimals]
|
|
317
|
+
else:
|
|
318
|
+
dec_str += "0" * (decimals - len(dec_str))
|
|
319
|
+
try:
|
|
320
|
+
dec_part = int(dec_str)
|
|
321
|
+
except ValueError:
|
|
322
|
+
raise ValueError(f"Invalid decimal part: {parts[1]}")
|
|
323
|
+
|
|
324
|
+
multiplier = 10**decimals
|
|
325
|
+
return int_part * multiplier + dec_part
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def format_amount(atomic_amount: int, decimals: int) -> str:
|
|
329
|
+
"""Convert atomic units to a human-readable decimal string.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
atomic_amount: Amount in smallest atomic units.
|
|
333
|
+
decimals: Number of decimal places for the token.
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
Formatted decimal string.
|
|
337
|
+
"""
|
|
338
|
+
if atomic_amount == 0:
|
|
339
|
+
return "0"
|
|
340
|
+
|
|
341
|
+
multiplier = 10**decimals
|
|
342
|
+
int_part = atomic_amount // multiplier
|
|
343
|
+
dec_part = atomic_amount % multiplier
|
|
344
|
+
|
|
345
|
+
if dec_part == 0:
|
|
346
|
+
return str(int_part)
|
|
347
|
+
|
|
348
|
+
dec_str = str(dec_part).zfill(decimals).rstrip("0")
|
|
349
|
+
return f"{int_part}.{dec_str}"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Aptos Exact-Direct Payment Scheme.
|
|
2
|
+
|
|
3
|
+
This package provides the exact-direct payment scheme implementation for Aptos
|
|
4
|
+
using Fungible Asset (FA) transfers via ``0x1::primary_fungible_store::transfer``.
|
|
5
|
+
|
|
6
|
+
The exact-direct scheme works as follows:
|
|
7
|
+
1. Client executes the FA transfer on-chain directly.
|
|
8
|
+
2. Client returns the transaction hash as proof of payment.
|
|
9
|
+
3. Facilitator queries the Aptos REST API to verify the transaction details.
|
|
10
|
+
|
|
11
|
+
This is a "push" payment model where the client performs the transfer first,
|
|
12
|
+
unlike permit-based models where the facilitator executes settlement.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from t402.schemes.aptos.exact_direct.client import (
|
|
16
|
+
ExactDirectAptosClientScheme,
|
|
17
|
+
)
|
|
18
|
+
from t402.schemes.aptos.exact_direct.server import (
|
|
19
|
+
ExactDirectAptosServerScheme,
|
|
20
|
+
)
|
|
21
|
+
from t402.schemes.aptos.exact_direct.facilitator import (
|
|
22
|
+
ExactDirectAptosFacilitatorScheme,
|
|
23
|
+
)
|
|
24
|
+
from t402.schemes.aptos.constants import SCHEME_EXACT_DIRECT
|
|
25
|
+
from t402.schemes.aptos.types import (
|
|
26
|
+
ClientAptosSigner,
|
|
27
|
+
FacilitatorAptosSigner,
|
|
28
|
+
ExactDirectPayload,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
# Client
|
|
33
|
+
"ExactDirectAptosClientScheme",
|
|
34
|
+
"ClientAptosSigner",
|
|
35
|
+
# Server
|
|
36
|
+
"ExactDirectAptosServerScheme",
|
|
37
|
+
# Facilitator
|
|
38
|
+
"ExactDirectAptosFacilitatorScheme",
|
|
39
|
+
"FacilitatorAptosSigner",
|
|
40
|
+
# Types
|
|
41
|
+
"ExactDirectPayload",
|
|
42
|
+
# Constants
|
|
43
|
+
"SCHEME_EXACT_DIRECT",
|
|
44
|
+
]
|