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/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,21 +70,113 @@ 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,
|
|
78
|
+
# Upto EVM
|
|
79
|
+
UptoEvmClientScheme,
|
|
80
|
+
UptoEvmServerScheme,
|
|
81
|
+
UptoEvmFacilitatorScheme,
|
|
82
|
+
PermitSignature,
|
|
83
|
+
PermitAuthorization,
|
|
84
|
+
UptoEIP2612Payload,
|
|
85
|
+
UptoEvmExtra,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Upto Core Types
|
|
89
|
+
from t402.schemes.upto import (
|
|
90
|
+
SCHEME_UPTO,
|
|
91
|
+
UptoPaymentRequirements,
|
|
92
|
+
UptoExtra,
|
|
93
|
+
UptoSettlement,
|
|
94
|
+
UptoUsageDetails,
|
|
95
|
+
UptoSettlementResponse,
|
|
96
|
+
UptoValidationResult,
|
|
97
|
+
is_upto_payment_requirements,
|
|
98
|
+
is_valid_unit,
|
|
99
|
+
create_payment_requirements as create_upto_requirements,
|
|
100
|
+
create_settlement as create_upto_settlement,
|
|
74
101
|
)
|
|
75
102
|
|
|
76
103
|
# TON Schemes
|
|
77
104
|
from t402.schemes.ton import (
|
|
78
105
|
ExactTonClientScheme,
|
|
79
106
|
ExactTonServerScheme,
|
|
107
|
+
ExactTonFacilitatorScheme,
|
|
80
108
|
TonSigner,
|
|
109
|
+
FacilitatorTonSigner,
|
|
81
110
|
)
|
|
82
111
|
|
|
83
112
|
# TRON Schemes
|
|
84
113
|
from t402.schemes.tron import (
|
|
85
114
|
ExactTronClientScheme,
|
|
86
115
|
ExactTronServerScheme,
|
|
116
|
+
ExactTronFacilitatorScheme,
|
|
117
|
+
ExactTronFacilitatorConfig,
|
|
87
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,
|
|
88
180
|
)
|
|
89
181
|
|
|
90
182
|
__all__ = [
|
|
@@ -110,16 +202,87 @@ __all__ = [
|
|
|
110
202
|
"get_server_registry",
|
|
111
203
|
"get_facilitator_registry",
|
|
112
204
|
"reset_global_registries",
|
|
113
|
-
# EVM Schemes
|
|
205
|
+
# EVM Exact Schemes
|
|
114
206
|
"ExactEvmClientScheme",
|
|
115
207
|
"ExactEvmServerScheme",
|
|
208
|
+
"ExactEvmFacilitatorScheme",
|
|
209
|
+
"FacilitatorEvmSigner",
|
|
210
|
+
"EvmVerifyResult",
|
|
211
|
+
"EvmTransactionConfirmation",
|
|
116
212
|
"EvmSigner",
|
|
213
|
+
# EVM Upto Schemes
|
|
214
|
+
"UptoEvmClientScheme",
|
|
215
|
+
"UptoEvmServerScheme",
|
|
216
|
+
"UptoEvmFacilitatorScheme",
|
|
217
|
+
"PermitSignature",
|
|
218
|
+
"PermitAuthorization",
|
|
219
|
+
"UptoEIP2612Payload",
|
|
220
|
+
"UptoEvmExtra",
|
|
221
|
+
# Upto Core Types
|
|
222
|
+
"SCHEME_UPTO",
|
|
223
|
+
"UptoPaymentRequirements",
|
|
224
|
+
"UptoExtra",
|
|
225
|
+
"UptoSettlement",
|
|
226
|
+
"UptoUsageDetails",
|
|
227
|
+
"UptoSettlementResponse",
|
|
228
|
+
"UptoValidationResult",
|
|
229
|
+
"is_upto_payment_requirements",
|
|
230
|
+
"is_valid_unit",
|
|
231
|
+
"create_upto_requirements",
|
|
232
|
+
"create_upto_settlement",
|
|
117
233
|
# TON Schemes
|
|
118
234
|
"ExactTonClientScheme",
|
|
119
235
|
"ExactTonServerScheme",
|
|
236
|
+
"ExactTonFacilitatorScheme",
|
|
120
237
|
"TonSigner",
|
|
238
|
+
"FacilitatorTonSigner",
|
|
121
239
|
# TRON Schemes
|
|
122
240
|
"ExactTronClientScheme",
|
|
123
241
|
"ExactTronServerScheme",
|
|
242
|
+
"ExactTronFacilitatorScheme",
|
|
243
|
+
"ExactTronFacilitatorConfig",
|
|
124
244
|
"TronSigner",
|
|
245
|
+
"FacilitatorTronSigner",
|
|
246
|
+
# SVM Schemes
|
|
247
|
+
"ExactSvmClientScheme",
|
|
248
|
+
"ExactSvmServerScheme",
|
|
249
|
+
"ExactSvmFacilitatorScheme",
|
|
250
|
+
"SvmClientSigner",
|
|
251
|
+
"SvmFacilitatorSigner",
|
|
252
|
+
"SVM_SCHEME_EXACT",
|
|
253
|
+
# NEAR Schemes
|
|
254
|
+
"ExactDirectNearClientScheme",
|
|
255
|
+
"ExactDirectNearServerScheme",
|
|
256
|
+
"ExactDirectNearFacilitatorScheme",
|
|
257
|
+
"ClientNearSigner",
|
|
258
|
+
"FacilitatorNearSigner",
|
|
259
|
+
"NEAR_SCHEME_EXACT_DIRECT",
|
|
260
|
+
# Aptos Schemes
|
|
261
|
+
"ExactDirectAptosClientScheme",
|
|
262
|
+
"ExactDirectAptosServerScheme",
|
|
263
|
+
"ExactDirectAptosFacilitatorScheme",
|
|
264
|
+
"ClientAptosSigner",
|
|
265
|
+
"FacilitatorAptosSigner",
|
|
266
|
+
"SCHEME_EXACT_DIRECT",
|
|
267
|
+
# Polkadot Schemes
|
|
268
|
+
"ExactDirectPolkadotClientScheme",
|
|
269
|
+
"ExactDirectPolkadotServerScheme",
|
|
270
|
+
"ExactDirectPolkadotFacilitatorScheme",
|
|
271
|
+
"ClientPolkadotSigner",
|
|
272
|
+
"FacilitatorPolkadotSigner",
|
|
273
|
+
"POLKADOT_SCHEME_EXACT_DIRECT",
|
|
274
|
+
# Tezos Schemes
|
|
275
|
+
"ExactDirectTezosClient",
|
|
276
|
+
"ExactDirectTezosServer",
|
|
277
|
+
"ExactDirectTezosFacilitator",
|
|
278
|
+
"ClientTezosSigner",
|
|
279
|
+
"FacilitatorTezosSigner",
|
|
280
|
+
"TEZOS_SCHEME_EXACT_DIRECT",
|
|
281
|
+
# Stacks Schemes
|
|
282
|
+
"ExactDirectStacksClientScheme",
|
|
283
|
+
"ExactDirectStacksServerScheme",
|
|
284
|
+
"ExactDirectStacksFacilitatorScheme",
|
|
285
|
+
"ClientStacksSigner",
|
|
286
|
+
"FacilitatorStacksSigner",
|
|
287
|
+
"STACKS_SCHEME_EXACT_DIRECT",
|
|
125
288
|
]
|
|
@@ -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}"
|