t402 1.4.0__py3-none-any.whl → 1.5.3__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 +61 -0
- t402/bridge/client.py +0 -1
- t402/bridge/types.py +0 -1
- t402/cli.py +324 -0
- t402/erc4337/accounts.py +1 -3
- t402/erc4337/paymasters.py +1 -3
- t402/erc4337/types.py +1 -2
- t402/fastapi/middleware.py +1 -1
- t402/flask/middleware.py +1 -1
- t402/wdk/__init__.py +140 -0
- t402/wdk/chains.py +245 -0
- t402/wdk/errors.py +211 -0
- t402/wdk/signer.py +657 -0
- t402/wdk/types.py +134 -0
- {t402-1.4.0.dist-info → t402-1.5.3.dist-info}/METADATA +201 -10
- {t402-1.4.0.dist-info → t402-1.5.3.dist-info}/RECORD +18 -11
- t402-1.5.3.dist-info/entry_points.txt +2 -0
- {t402-1.4.0.dist-info → t402-1.5.3.dist-info}/WHEEL +0 -0
t402/__init__.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# Package version
|
|
2
|
+
__version__ = "1.5.3"
|
|
3
|
+
|
|
1
4
|
# Re-export commonly used items for convenience
|
|
2
5
|
from t402.common import (
|
|
3
6
|
parse_money,
|
|
@@ -117,12 +120,43 @@ from t402.bridge import (
|
|
|
117
120
|
CrossChainPaymentParams,
|
|
118
121
|
CrossChainPaymentResult,
|
|
119
122
|
)
|
|
123
|
+
from t402.wdk import (
|
|
124
|
+
# Signer
|
|
125
|
+
WDKSigner,
|
|
126
|
+
generate_seed_phrase,
|
|
127
|
+
validate_seed_phrase,
|
|
128
|
+
# Types
|
|
129
|
+
WDKConfig,
|
|
130
|
+
ChainConfig as WDKChainConfig,
|
|
131
|
+
NetworkType,
|
|
132
|
+
TokenInfo as WDKTokenInfo,
|
|
133
|
+
TokenBalance,
|
|
134
|
+
ChainBalance,
|
|
135
|
+
AggregatedBalance,
|
|
136
|
+
PaymentParams,
|
|
137
|
+
PaymentResult,
|
|
138
|
+
SignedTypedData,
|
|
139
|
+
# Chain utilities
|
|
140
|
+
DEFAULT_CHAINS as WDK_DEFAULT_CHAINS,
|
|
141
|
+
USDT0_ADDRESSES as WDK_USDT0_ADDRESSES,
|
|
142
|
+
get_chain_config as get_wdk_chain_config,
|
|
143
|
+
get_usdt0_chains as get_wdk_usdt0_chains,
|
|
144
|
+
# Errors
|
|
145
|
+
WDKError,
|
|
146
|
+
WDKInitializationError,
|
|
147
|
+
SignerError,
|
|
148
|
+
SigningError,
|
|
149
|
+
BalanceError as WDKBalanceError,
|
|
150
|
+
WDKErrorCode,
|
|
151
|
+
)
|
|
120
152
|
|
|
121
153
|
def hello() -> str:
|
|
122
154
|
return "Hello from t402!"
|
|
123
155
|
|
|
124
156
|
|
|
125
157
|
__all__ = [
|
|
158
|
+
# Version
|
|
159
|
+
"__version__",
|
|
126
160
|
# Core
|
|
127
161
|
"hello",
|
|
128
162
|
"t402_VERSION",
|
|
@@ -226,4 +260,31 @@ __all__ = [
|
|
|
226
260
|
"LayerZeroMessageStatus",
|
|
227
261
|
"CrossChainPaymentParams",
|
|
228
262
|
"CrossChainPaymentResult",
|
|
263
|
+
# WDK - Signer
|
|
264
|
+
"WDKSigner",
|
|
265
|
+
"generate_seed_phrase",
|
|
266
|
+
"validate_seed_phrase",
|
|
267
|
+
# WDK - Types
|
|
268
|
+
"WDKConfig",
|
|
269
|
+
"WDKChainConfig",
|
|
270
|
+
"NetworkType",
|
|
271
|
+
"WDKTokenInfo",
|
|
272
|
+
"TokenBalance",
|
|
273
|
+
"ChainBalance",
|
|
274
|
+
"AggregatedBalance",
|
|
275
|
+
"PaymentParams",
|
|
276
|
+
"PaymentResult",
|
|
277
|
+
"SignedTypedData",
|
|
278
|
+
# WDK - Chain utilities
|
|
279
|
+
"WDK_DEFAULT_CHAINS",
|
|
280
|
+
"WDK_USDT0_ADDRESSES",
|
|
281
|
+
"get_wdk_chain_config",
|
|
282
|
+
"get_wdk_usdt0_chains",
|
|
283
|
+
# WDK - Errors
|
|
284
|
+
"WDKError",
|
|
285
|
+
"WDKInitializationError",
|
|
286
|
+
"SignerError",
|
|
287
|
+
"SigningError",
|
|
288
|
+
"WDKBalanceError",
|
|
289
|
+
"WDKErrorCode",
|
|
229
290
|
]
|
t402/bridge/client.py
CHANGED
t402/bridge/types.py
CHANGED
t402/cli.py
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
T402 CLI - Command-line interface for the T402 payment protocol.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
t402 verify <payment-payload> [--facilitator URL]
|
|
7
|
+
t402 settle <payment-payload> [--facilitator URL]
|
|
8
|
+
t402 supported [--facilitator URL]
|
|
9
|
+
t402 encode <json-file>
|
|
10
|
+
t402 decode <base64-string>
|
|
11
|
+
t402 version
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import argparse
|
|
16
|
+
import asyncio
|
|
17
|
+
import json
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any
|
|
21
|
+
|
|
22
|
+
from . import __version__
|
|
23
|
+
from .encoding import decode_payment, encode_payment
|
|
24
|
+
from .facilitator import FacilitatorClient, FacilitatorConfig
|
|
25
|
+
from .types import PaymentPayload
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def create_parser() -> argparse.ArgumentParser:
|
|
29
|
+
"""Create the argument parser for the CLI."""
|
|
30
|
+
parser = argparse.ArgumentParser(
|
|
31
|
+
prog="t402",
|
|
32
|
+
description="T402 Payment Protocol CLI",
|
|
33
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
34
|
+
epilog="""
|
|
35
|
+
Examples:
|
|
36
|
+
# Verify a payment
|
|
37
|
+
t402 verify <base64-encoded-payload>
|
|
38
|
+
|
|
39
|
+
# Settle a payment
|
|
40
|
+
t402 settle <base64-encoded-payload>
|
|
41
|
+
|
|
42
|
+
# List supported networks and schemes
|
|
43
|
+
t402 supported
|
|
44
|
+
|
|
45
|
+
# Encode a payment payload from JSON
|
|
46
|
+
t402 encode payment.json
|
|
47
|
+
|
|
48
|
+
# Decode a base64 payment payload
|
|
49
|
+
t402 decode <base64-string>
|
|
50
|
+
""",
|
|
51
|
+
)
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"-v", "--version", action="version", version=f"t402 {__version__}"
|
|
54
|
+
)
|
|
55
|
+
parser.add_argument(
|
|
56
|
+
"-f",
|
|
57
|
+
"--facilitator",
|
|
58
|
+
default="https://facilitator.t402.io",
|
|
59
|
+
help="Facilitator URL (default: https://facilitator.t402.io)",
|
|
60
|
+
)
|
|
61
|
+
parser.add_argument(
|
|
62
|
+
"-o",
|
|
63
|
+
"--output",
|
|
64
|
+
choices=["json", "text"],
|
|
65
|
+
default="text",
|
|
66
|
+
help="Output format (default: text)",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
70
|
+
|
|
71
|
+
# verify command
|
|
72
|
+
verify_parser = subparsers.add_parser("verify", help="Verify a payment payload")
|
|
73
|
+
verify_parser.add_argument("payload", help="Base64-encoded payment payload")
|
|
74
|
+
|
|
75
|
+
# settle command
|
|
76
|
+
settle_parser = subparsers.add_parser("settle", help="Settle a payment")
|
|
77
|
+
settle_parser.add_argument("payload", help="Base64-encoded payment payload")
|
|
78
|
+
|
|
79
|
+
# supported command
|
|
80
|
+
subparsers.add_parser("supported", help="List supported networks and schemes")
|
|
81
|
+
|
|
82
|
+
# encode command
|
|
83
|
+
encode_parser = subparsers.add_parser(
|
|
84
|
+
"encode", help="Encode a payment payload from JSON"
|
|
85
|
+
)
|
|
86
|
+
encode_parser.add_argument(
|
|
87
|
+
"file", type=Path, help="JSON file containing payment payload"
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# decode command
|
|
91
|
+
decode_parser = subparsers.add_parser(
|
|
92
|
+
"decode", help="Decode a base64-encoded payment payload"
|
|
93
|
+
)
|
|
94
|
+
decode_parser.add_argument("payload", help="Base64-encoded payment payload")
|
|
95
|
+
|
|
96
|
+
# info command
|
|
97
|
+
info_parser = subparsers.add_parser("info", help="Show information about a network")
|
|
98
|
+
info_parser.add_argument("network", help="Network identifier (e.g., eip155:1)")
|
|
99
|
+
|
|
100
|
+
return parser
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def output_result(result: Any, output_format: str) -> None:
|
|
104
|
+
"""Output result in the specified format."""
|
|
105
|
+
if output_format == "json":
|
|
106
|
+
if hasattr(result, "model_dump"):
|
|
107
|
+
print(json.dumps(result.model_dump(), indent=2))
|
|
108
|
+
elif isinstance(result, dict):
|
|
109
|
+
print(json.dumps(result, indent=2))
|
|
110
|
+
else:
|
|
111
|
+
print(json.dumps({"result": str(result)}, indent=2))
|
|
112
|
+
else:
|
|
113
|
+
if isinstance(result, dict):
|
|
114
|
+
for key, value in result.items():
|
|
115
|
+
print(f"{key}: {value}")
|
|
116
|
+
else:
|
|
117
|
+
print(result)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
async def cmd_verify(args: argparse.Namespace) -> int:
|
|
121
|
+
"""Verify a payment payload."""
|
|
122
|
+
try:
|
|
123
|
+
config = FacilitatorConfig(base_url=args.facilitator)
|
|
124
|
+
client = FacilitatorClient(config)
|
|
125
|
+
|
|
126
|
+
# Decode the payload first
|
|
127
|
+
payload_dict = decode_payment(args.payload)
|
|
128
|
+
payload = PaymentPayload.model_validate(payload_dict)
|
|
129
|
+
|
|
130
|
+
result = await client.verify(payload)
|
|
131
|
+
|
|
132
|
+
if args.output == "json":
|
|
133
|
+
print(json.dumps({"valid": result.valid, "error": result.error}, indent=2))
|
|
134
|
+
else:
|
|
135
|
+
if result.valid:
|
|
136
|
+
print("Payment is VALID")
|
|
137
|
+
else:
|
|
138
|
+
print(f"Payment is INVALID: {result.error}")
|
|
139
|
+
|
|
140
|
+
return 0 if result.valid else 1
|
|
141
|
+
except Exception as e:
|
|
142
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
143
|
+
return 1
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
async def cmd_settle(args: argparse.Namespace) -> int:
|
|
147
|
+
"""Settle a payment."""
|
|
148
|
+
try:
|
|
149
|
+
config = FacilitatorConfig(base_url=args.facilitator)
|
|
150
|
+
client = FacilitatorClient(config)
|
|
151
|
+
|
|
152
|
+
# Decode the payload first
|
|
153
|
+
payload_dict = decode_payment(args.payload)
|
|
154
|
+
payload = PaymentPayload.model_validate(payload_dict)
|
|
155
|
+
|
|
156
|
+
result = await client.settle(payload)
|
|
157
|
+
|
|
158
|
+
if args.output == "json":
|
|
159
|
+
print(
|
|
160
|
+
json.dumps(
|
|
161
|
+
{
|
|
162
|
+
"success": result.success,
|
|
163
|
+
"transaction_hash": result.transaction_hash,
|
|
164
|
+
"error": result.error,
|
|
165
|
+
},
|
|
166
|
+
indent=2,
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
else:
|
|
170
|
+
if result.success:
|
|
171
|
+
print("Payment settled successfully!")
|
|
172
|
+
print(f"Transaction hash: {result.transaction_hash}")
|
|
173
|
+
else:
|
|
174
|
+
print(f"Settlement failed: {result.error}")
|
|
175
|
+
|
|
176
|
+
return 0 if result.success else 1
|
|
177
|
+
except Exception as e:
|
|
178
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
179
|
+
return 1
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
async def cmd_supported(args: argparse.Namespace) -> int:
|
|
183
|
+
"""List supported networks and schemes."""
|
|
184
|
+
try:
|
|
185
|
+
config = FacilitatorConfig(base_url=args.facilitator)
|
|
186
|
+
client = FacilitatorClient(config)
|
|
187
|
+
|
|
188
|
+
result = await client.list_supported()
|
|
189
|
+
|
|
190
|
+
if args.output == "json":
|
|
191
|
+
print(
|
|
192
|
+
json.dumps(
|
|
193
|
+
{
|
|
194
|
+
"kinds": [k.model_dump() for k in result.kinds],
|
|
195
|
+
"signers": result.signers,
|
|
196
|
+
"extensions": result.extensions,
|
|
197
|
+
},
|
|
198
|
+
indent=2,
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
print("Supported Payment Kinds:")
|
|
203
|
+
print("-" * 50)
|
|
204
|
+
for kind in result.kinds:
|
|
205
|
+
print(f" Scheme: {kind.scheme}")
|
|
206
|
+
print(f" Network: {kind.network}")
|
|
207
|
+
if hasattr(kind, "token") and kind.token:
|
|
208
|
+
print(f" Token: {kind.token}")
|
|
209
|
+
print()
|
|
210
|
+
|
|
211
|
+
if result.signers:
|
|
212
|
+
print("Supported Signers:")
|
|
213
|
+
for signer in result.signers:
|
|
214
|
+
print(f" - {signer}")
|
|
215
|
+
print()
|
|
216
|
+
|
|
217
|
+
if result.extensions:
|
|
218
|
+
print("Supported Extensions:")
|
|
219
|
+
for ext in result.extensions:
|
|
220
|
+
print(f" - {ext}")
|
|
221
|
+
|
|
222
|
+
return 0
|
|
223
|
+
except Exception as e:
|
|
224
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
225
|
+
return 1
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def cmd_encode(args: argparse.Namespace) -> int:
|
|
229
|
+
"""Encode a payment payload from JSON."""
|
|
230
|
+
try:
|
|
231
|
+
with open(args.file) as f:
|
|
232
|
+
payload_dict = json.load(f)
|
|
233
|
+
|
|
234
|
+
encoded = encode_payment(payload_dict)
|
|
235
|
+
print(encoded)
|
|
236
|
+
return 0
|
|
237
|
+
except FileNotFoundError:
|
|
238
|
+
print(f"Error: File not found: {args.file}", file=sys.stderr)
|
|
239
|
+
return 1
|
|
240
|
+
except json.JSONDecodeError as e:
|
|
241
|
+
print(f"Error: Invalid JSON: {e}", file=sys.stderr)
|
|
242
|
+
return 1
|
|
243
|
+
except Exception as e:
|
|
244
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
245
|
+
return 1
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def cmd_decode(args: argparse.Namespace) -> int:
|
|
249
|
+
"""Decode a base64-encoded payment payload."""
|
|
250
|
+
try:
|
|
251
|
+
decoded = decode_payment(args.payload)
|
|
252
|
+
|
|
253
|
+
if args.output == "json":
|
|
254
|
+
print(json.dumps(decoded, indent=2))
|
|
255
|
+
else:
|
|
256
|
+
print(json.dumps(decoded, indent=2))
|
|
257
|
+
|
|
258
|
+
return 0
|
|
259
|
+
except Exception as e:
|
|
260
|
+
print(f"Error: Failed to decode payload: {e}", file=sys.stderr)
|
|
261
|
+
return 1
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def cmd_info(args: argparse.Namespace) -> int:
|
|
265
|
+
"""Show information about a network."""
|
|
266
|
+
from .networks import is_evm_network, is_ton_network, is_tron_network
|
|
267
|
+
|
|
268
|
+
network = args.network
|
|
269
|
+
|
|
270
|
+
info = {
|
|
271
|
+
"network": network,
|
|
272
|
+
"is_evm": is_evm_network(network),
|
|
273
|
+
"is_ton": is_ton_network(network),
|
|
274
|
+
"is_tron": is_tron_network(network),
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
# Add chain-specific info
|
|
278
|
+
if is_evm_network(network):
|
|
279
|
+
from .chains import EVM_CHAINS
|
|
280
|
+
|
|
281
|
+
chain_id = network.split(":")[1] if ":" in network else network
|
|
282
|
+
if chain_id in EVM_CHAINS:
|
|
283
|
+
chain = EVM_CHAINS[chain_id]
|
|
284
|
+
info["chain_name"] = chain.get("name", "Unknown")
|
|
285
|
+
info["currency"] = chain.get("currency", "Unknown")
|
|
286
|
+
|
|
287
|
+
if args.output == "json":
|
|
288
|
+
print(json.dumps(info, indent=2))
|
|
289
|
+
else:
|
|
290
|
+
for key, value in info.items():
|
|
291
|
+
print(f"{key}: {value}")
|
|
292
|
+
|
|
293
|
+
return 0
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
def main() -> int:
|
|
297
|
+
"""Main entry point for the CLI."""
|
|
298
|
+
parser = create_parser()
|
|
299
|
+
args = parser.parse_args()
|
|
300
|
+
|
|
301
|
+
if not args.command:
|
|
302
|
+
parser.print_help()
|
|
303
|
+
return 0
|
|
304
|
+
|
|
305
|
+
# Route to the appropriate command handler
|
|
306
|
+
if args.command == "verify":
|
|
307
|
+
return asyncio.run(cmd_verify(args))
|
|
308
|
+
elif args.command == "settle":
|
|
309
|
+
return asyncio.run(cmd_settle(args))
|
|
310
|
+
elif args.command == "supported":
|
|
311
|
+
return asyncio.run(cmd_supported(args))
|
|
312
|
+
elif args.command == "encode":
|
|
313
|
+
return cmd_encode(args)
|
|
314
|
+
elif args.command == "decode":
|
|
315
|
+
return cmd_decode(args)
|
|
316
|
+
elif args.command == "info":
|
|
317
|
+
return cmd_info(args)
|
|
318
|
+
else:
|
|
319
|
+
parser.print_help()
|
|
320
|
+
return 0
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
if __name__ == "__main__":
|
|
324
|
+
sys.exit(main())
|
t402/erc4337/accounts.py
CHANGED
|
@@ -6,7 +6,7 @@ including Safe smart account with 4337 module support.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
|
-
from typing import Optional, List
|
|
9
|
+
from typing import Optional, List
|
|
10
10
|
from abc import ABC, abstractmethod
|
|
11
11
|
from eth_account import Account
|
|
12
12
|
from eth_account.messages import encode_defunct
|
|
@@ -95,8 +95,6 @@ class SafeSmartAccount(SmartAccountSigner):
|
|
|
95
95
|
return self._cached_address
|
|
96
96
|
|
|
97
97
|
# Calculate counterfactual address via CREATE2
|
|
98
|
-
init_code = self.get_init_code()
|
|
99
|
-
|
|
100
98
|
factory_address = bytes.fromhex(SAFE_4337_ADDRESSES["proxy_factory"][2:])
|
|
101
99
|
salt_hash = self._calculate_salt()
|
|
102
100
|
proxy_init_code = self._get_proxy_creation_code()
|
t402/erc4337/paymasters.py
CHANGED
|
@@ -6,15 +6,13 @@ gas sponsorship, including Pimlico, Biconomy, and Stackup clients.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import httpx
|
|
9
|
-
from
|
|
10
|
-
from typing import Optional, List, Dict, Any, Union
|
|
9
|
+
from typing import Optional, List, Dict, Any
|
|
11
10
|
from abc import ABC, abstractmethod
|
|
12
11
|
|
|
13
12
|
from .types import (
|
|
14
13
|
UserOperation,
|
|
15
14
|
PaymasterData,
|
|
16
15
|
TokenQuote,
|
|
17
|
-
GasEstimate,
|
|
18
16
|
ENTRYPOINT_V07_ADDRESS,
|
|
19
17
|
PIMLICO_NETWORKS,
|
|
20
18
|
DEFAULT_GAS_LIMITS,
|
t402/erc4337/types.py
CHANGED
|
@@ -7,8 +7,7 @@ bundler interactions, and paymaster integration.
|
|
|
7
7
|
|
|
8
8
|
from dataclasses import dataclass, field
|
|
9
9
|
from enum import Enum
|
|
10
|
-
from typing import Optional, List
|
|
11
|
-
from eth_typing import HexStr, Address
|
|
10
|
+
from typing import Optional, List
|
|
12
11
|
|
|
13
12
|
# EntryPoint addresses (canonical deployments)
|
|
14
13
|
ENTRYPOINT_V07_ADDRESS = "0x0000000071727De22E5E9d8BAf0edAc6f37da032"
|
t402/fastapi/middleware.py
CHANGED
|
@@ -108,7 +108,7 @@ def require_payment(
|
|
|
108
108
|
mime_type=mime_type,
|
|
109
109
|
pay_to=pay_to_address,
|
|
110
110
|
max_timeout_seconds=max_deadline_seconds,
|
|
111
|
-
#
|
|
111
|
+
# Contains both input and output schema (field name kept for backwards compatibility)
|
|
112
112
|
output_schema={
|
|
113
113
|
"input": {
|
|
114
114
|
"type": "http",
|
t402/flask/middleware.py
CHANGED
|
@@ -192,7 +192,7 @@ class PaymentMiddleware:
|
|
|
192
192
|
mime_type=config["mime_type"],
|
|
193
193
|
pay_to=config["pay_to_address"],
|
|
194
194
|
max_timeout_seconds=config["max_deadline_seconds"],
|
|
195
|
-
#
|
|
195
|
+
# Contains both input and output schema (field name kept for backwards compatibility)
|
|
196
196
|
output_schema={
|
|
197
197
|
"input": {
|
|
198
198
|
"type": "http",
|
t402/wdk/__init__.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""
|
|
2
|
+
T402 WDK Python Adapter
|
|
3
|
+
|
|
4
|
+
Provides wallet functionality for T402 payments using Tether WDK-compatible
|
|
5
|
+
seed phrase derivation.
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
```python
|
|
9
|
+
from t402.wdk import WDKSigner, generate_seed_phrase
|
|
10
|
+
|
|
11
|
+
# Generate a new seed phrase
|
|
12
|
+
seed = generate_seed_phrase()
|
|
13
|
+
|
|
14
|
+
# Create signer
|
|
15
|
+
signer = WDKSigner(
|
|
16
|
+
seed_phrase=seed,
|
|
17
|
+
chains={"arbitrum": "https://arb1.arbitrum.io/rpc"}
|
|
18
|
+
)
|
|
19
|
+
await signer.initialize()
|
|
20
|
+
|
|
21
|
+
# Get address
|
|
22
|
+
address = signer.get_address("evm")
|
|
23
|
+
|
|
24
|
+
# Get balances
|
|
25
|
+
balances = await signer.get_all_balances()
|
|
26
|
+
```
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from .signer import (
|
|
30
|
+
WDKSigner,
|
|
31
|
+
generate_seed_phrase,
|
|
32
|
+
validate_seed_phrase,
|
|
33
|
+
format_token_amount,
|
|
34
|
+
)
|
|
35
|
+
from .types import (
|
|
36
|
+
# Core types
|
|
37
|
+
WDKConfig,
|
|
38
|
+
ChainConfig,
|
|
39
|
+
NetworkType,
|
|
40
|
+
# Token types
|
|
41
|
+
TokenInfo,
|
|
42
|
+
TokenBalance,
|
|
43
|
+
ChainBalance,
|
|
44
|
+
AggregatedBalance,
|
|
45
|
+
# Payment types
|
|
46
|
+
PaymentParams,
|
|
47
|
+
PaymentResult,
|
|
48
|
+
SignedTypedData,
|
|
49
|
+
TypedDataDomain,
|
|
50
|
+
# Bridge types
|
|
51
|
+
BridgeParams,
|
|
52
|
+
BridgeResult,
|
|
53
|
+
)
|
|
54
|
+
from .chains import (
|
|
55
|
+
# Chain configuration
|
|
56
|
+
DEFAULT_CHAINS,
|
|
57
|
+
CHAIN_TOKENS,
|
|
58
|
+
# Token addresses
|
|
59
|
+
USDT0_ADDRESSES,
|
|
60
|
+
USDC_ADDRESSES,
|
|
61
|
+
USDT_LEGACY_ADDRESSES,
|
|
62
|
+
# Utility functions
|
|
63
|
+
get_chain_config,
|
|
64
|
+
get_chain_id,
|
|
65
|
+
get_network_from_chain,
|
|
66
|
+
get_chain_from_network,
|
|
67
|
+
get_usdt0_chains,
|
|
68
|
+
get_chain_tokens,
|
|
69
|
+
get_preferred_token,
|
|
70
|
+
get_token_address,
|
|
71
|
+
is_testnet,
|
|
72
|
+
)
|
|
73
|
+
from .errors import (
|
|
74
|
+
# Error classes
|
|
75
|
+
WDKError,
|
|
76
|
+
WDKInitializationError,
|
|
77
|
+
SignerError,
|
|
78
|
+
SigningError,
|
|
79
|
+
ChainError,
|
|
80
|
+
BalanceError,
|
|
81
|
+
TransactionError,
|
|
82
|
+
BridgeError,
|
|
83
|
+
# Error codes
|
|
84
|
+
WDKErrorCode,
|
|
85
|
+
# Utilities
|
|
86
|
+
is_wdk_error,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
__all__ = [
|
|
91
|
+
# Signer
|
|
92
|
+
"WDKSigner",
|
|
93
|
+
"generate_seed_phrase",
|
|
94
|
+
"validate_seed_phrase",
|
|
95
|
+
"format_token_amount",
|
|
96
|
+
# Core types
|
|
97
|
+
"WDKConfig",
|
|
98
|
+
"ChainConfig",
|
|
99
|
+
"NetworkType",
|
|
100
|
+
# Token types
|
|
101
|
+
"TokenInfo",
|
|
102
|
+
"TokenBalance",
|
|
103
|
+
"ChainBalance",
|
|
104
|
+
"AggregatedBalance",
|
|
105
|
+
# Payment types
|
|
106
|
+
"PaymentParams",
|
|
107
|
+
"PaymentResult",
|
|
108
|
+
"SignedTypedData",
|
|
109
|
+
"TypedDataDomain",
|
|
110
|
+
# Bridge types
|
|
111
|
+
"BridgeParams",
|
|
112
|
+
"BridgeResult",
|
|
113
|
+
# Chain configuration
|
|
114
|
+
"DEFAULT_CHAINS",
|
|
115
|
+
"CHAIN_TOKENS",
|
|
116
|
+
"USDT0_ADDRESSES",
|
|
117
|
+
"USDC_ADDRESSES",
|
|
118
|
+
"USDT_LEGACY_ADDRESSES",
|
|
119
|
+
# Chain utilities
|
|
120
|
+
"get_chain_config",
|
|
121
|
+
"get_chain_id",
|
|
122
|
+
"get_network_from_chain",
|
|
123
|
+
"get_chain_from_network",
|
|
124
|
+
"get_usdt0_chains",
|
|
125
|
+
"get_chain_tokens",
|
|
126
|
+
"get_preferred_token",
|
|
127
|
+
"get_token_address",
|
|
128
|
+
"is_testnet",
|
|
129
|
+
# Error classes
|
|
130
|
+
"WDKError",
|
|
131
|
+
"WDKInitializationError",
|
|
132
|
+
"SignerError",
|
|
133
|
+
"SigningError",
|
|
134
|
+
"ChainError",
|
|
135
|
+
"BalanceError",
|
|
136
|
+
"TransactionError",
|
|
137
|
+
"BridgeError",
|
|
138
|
+
"WDKErrorCode",
|
|
139
|
+
"is_wdk_error",
|
|
140
|
+
]
|