uvd-x402-sdk 0.2.1__py3-none-any.whl → 0.2.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.
uvd_x402_sdk/config.py CHANGED
@@ -1,248 +1,248 @@
1
- """
2
- SDK configuration classes.
3
-
4
- This module provides configuration management for the x402 SDK,
5
- including facilitator settings, recipient addresses, and timeouts.
6
-
7
- Supports:
8
- - x402 v1 and v2 protocols
9
- - Multi-network payment options
10
- - Per-network recipient configuration
11
- """
12
-
13
- from dataclasses import dataclass, field
14
- from typing import Dict, List, Optional, Any, Literal
15
- import os
16
-
17
-
18
- @dataclass
19
- class NetworkRecipientConfig:
20
- """
21
- Configuration for a specific network's recipient address.
22
-
23
- Use this to specify different recipient addresses for different networks.
24
- """
25
-
26
- recipient: str
27
- enabled: bool = True
28
-
29
-
30
- # Alias for backward compatibility
31
- NetworkConfig = NetworkRecipientConfig
32
-
33
-
34
- @dataclass
35
- class MultiPaymentConfig:
36
- """
37
- Configuration for multi-payment support.
38
-
39
- Allows users to offer multiple networks for payment acceptance.
40
- """
41
-
42
- networks: List[str] = field(default_factory=list)
43
- default_network: Optional[str] = None
44
-
45
- def __post_init__(self) -> None:
46
- if self.networks and not self.default_network:
47
- self.default_network = self.networks[0]
48
-
49
-
50
- @dataclass
51
- class X402Config:
52
- """
53
- Main SDK configuration.
54
-
55
- Attributes:
56
- facilitator_url: URL of the x402 facilitator service
57
- recipient_evm: Default recipient address for EVM chains
58
- recipient_solana: Recipient address for Solana/SVM chains (also used for Fogo)
59
- recipient_near: Recipient account for NEAR
60
- recipient_stellar: Recipient address for Stellar
61
- facilitator_solana: Solana/SVM facilitator address (fee payer)
62
- verify_timeout: Timeout for verify requests (seconds)
63
- settle_timeout: Timeout for settle requests (seconds)
64
- supported_networks: List of enabled network names
65
- network_configs: Per-network recipient overrides
66
- resource_url: Resource URL sent to facilitator
67
- description: Description sent to facilitator
68
- x402_version: Protocol version to use (1, 2, or "auto")
69
- multi_payment: Multi-payment configuration for accepting multiple networks
70
- """
71
-
72
- facilitator_url: str = "https://facilitator.ultravioletadao.xyz"
73
-
74
- # Recipient addresses per network type
75
- recipient_evm: str = ""
76
- recipient_solana: str = "" # Also used for Fogo and other SVM chains
77
- recipient_near: str = ""
78
- recipient_stellar: str = ""
79
-
80
- # Solana/SVM facilitator (fee payer) - same for all SVM chains
81
- facilitator_solana: str = "F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq"
82
-
83
- # Timeouts
84
- verify_timeout: float = 30.0
85
- settle_timeout: float = 55.0 # Must be < Lambda timeout (60s)
86
-
87
- # Network configuration - All 14 networks
88
- supported_networks: List[str] = field(default_factory=lambda: [
89
- # EVM chains (10)
90
- "base", "ethereum", "polygon", "arbitrum", "optimism",
91
- "avalanche", "celo", "hyperevm", "unichain", "monad",
92
- # SVM chains (2)
93
- "solana", "fogo",
94
- # NEAR (1)
95
- "near",
96
- # Stellar (1)
97
- "stellar",
98
- ])
99
-
100
- # Per-network recipient overrides
101
- network_configs: Dict[str, NetworkRecipientConfig] = field(default_factory=dict)
102
-
103
- # Facilitator request metadata
104
- resource_url: str = ""
105
- description: str = "x402 payment"
106
-
107
- # x402 protocol version: 1, 2, or "auto" (detect from payload)
108
- x402_version: Literal[1, 2, "auto"] = "auto"
109
-
110
- # Multi-payment configuration
111
- multi_payment: Optional[MultiPaymentConfig] = None
112
-
113
- def __post_init__(self) -> None:
114
- """Validate configuration after initialization."""
115
- if not self.facilitator_url:
116
- raise ValueError("facilitator_url is required")
117
-
118
- # At least one recipient is required
119
- if not any([
120
- self.recipient_evm,
121
- self.recipient_solana,
122
- self.recipient_near,
123
- self.recipient_stellar,
124
- ]):
125
- raise ValueError("At least one recipient address is required")
126
-
127
- @classmethod
128
- def from_env(cls) -> "X402Config":
129
- """
130
- Create configuration from environment variables.
131
-
132
- Environment variables:
133
- X402_FACILITATOR_URL: Facilitator URL
134
- X402_RECIPIENT_EVM: EVM recipient address
135
- X402_RECIPIENT_SOLANA: Solana recipient address
136
- X402_RECIPIENT_NEAR: NEAR recipient account
137
- X402_RECIPIENT_STELLAR: Stellar recipient address
138
- X402_FACILITATOR_SOLANA: Solana fee payer address
139
- X402_VERIFY_TIMEOUT: Verify request timeout
140
- X402_SETTLE_TIMEOUT: Settle request timeout
141
- X402_RESOURCE_URL: Resource URL for facilitator
142
- X402_DESCRIPTION: Description for facilitator
143
- """
144
- return cls(
145
- facilitator_url=os.environ.get(
146
- "X402_FACILITATOR_URL",
147
- "https://facilitator.ultravioletadao.xyz",
148
- ),
149
- recipient_evm=os.environ.get("X402_RECIPIENT_EVM", ""),
150
- recipient_solana=os.environ.get("X402_RECIPIENT_SOLANA", ""),
151
- recipient_near=os.environ.get("X402_RECIPIENT_NEAR", ""),
152
- recipient_stellar=os.environ.get("X402_RECIPIENT_STELLAR", ""),
153
- facilitator_solana=os.environ.get(
154
- "X402_FACILITATOR_SOLANA",
155
- "F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq",
156
- ),
157
- verify_timeout=float(os.environ.get("X402_VERIFY_TIMEOUT", "30")),
158
- settle_timeout=float(os.environ.get("X402_SETTLE_TIMEOUT", "55")),
159
- resource_url=os.environ.get("X402_RESOURCE_URL", ""),
160
- description=os.environ.get("X402_DESCRIPTION", "x402 payment"),
161
- )
162
-
163
- def get_recipient(self, network: str) -> str:
164
- """
165
- Get recipient address for a specific network.
166
-
167
- First checks network_configs for overrides, then falls back to
168
- network-type default.
169
-
170
- Args:
171
- network: Network name (e.g., 'base', 'solana', 'fogo')
172
-
173
- Returns:
174
- Recipient address for the network
175
- """
176
- # Check for network-specific override
177
- if network in self.network_configs:
178
- return self.network_configs[network].recipient
179
-
180
- # Fall back to network-type default
181
- from uvd_x402_sdk.networks import get_network, NetworkType
182
-
183
- network_config = get_network(network)
184
- if not network_config:
185
- return self.recipient_evm # Default to EVM
186
-
187
- # SVM chains (Solana, Fogo, etc.) use the same recipient
188
- if NetworkType.is_svm(network_config.network_type):
189
- return self.recipient_solana
190
- elif network_config.network_type == NetworkType.NEAR:
191
- return self.recipient_near
192
- elif network_config.network_type == NetworkType.STELLAR:
193
- return self.recipient_stellar
194
- else:
195
- return self.recipient_evm
196
-
197
- def is_network_enabled(self, network: str) -> bool:
198
- """
199
- Check if a network is enabled.
200
-
201
- Args:
202
- network: Network name
203
-
204
- Returns:
205
- True if network is in supported_networks and not disabled
206
- """
207
- if network not in self.supported_networks:
208
- return False
209
-
210
- # Check network-specific config
211
- if network in self.network_configs:
212
- return self.network_configs[network].enabled
213
-
214
- return True
215
-
216
- def get_supported_chain_ids(self) -> List[int]:
217
- """
218
- Get list of supported EVM chain IDs.
219
-
220
- Returns:
221
- List of chain IDs for enabled EVM networks
222
- """
223
- from uvd_x402_sdk.networks import get_network, NetworkType
224
-
225
- chain_ids = []
226
- for network_name in self.supported_networks:
227
- network = get_network(network_name)
228
- if network and network.network_type == NetworkType.EVM and network.chain_id > 0:
229
- if self.is_network_enabled(network_name):
230
- chain_ids.append(network.chain_id)
231
-
232
- return chain_ids
233
-
234
- def to_dict(self) -> Dict[str, Any]:
235
- """Convert configuration to dictionary."""
236
- return {
237
- "facilitator_url": self.facilitator_url,
238
- "recipient_evm": self.recipient_evm,
239
- "recipient_solana": self.recipient_solana,
240
- "recipient_near": self.recipient_near,
241
- "recipient_stellar": self.recipient_stellar,
242
- "facilitator_solana": self.facilitator_solana,
243
- "verify_timeout": self.verify_timeout,
244
- "settle_timeout": self.settle_timeout,
245
- "supported_networks": self.supported_networks,
246
- "resource_url": self.resource_url,
247
- "description": self.description,
248
- }
1
+ """
2
+ SDK configuration classes.
3
+
4
+ This module provides configuration management for the x402 SDK,
5
+ including facilitator settings, recipient addresses, and timeouts.
6
+
7
+ Supports:
8
+ - x402 v1 and v2 protocols
9
+ - Multi-network payment options
10
+ - Per-network recipient configuration
11
+ """
12
+
13
+ from dataclasses import dataclass, field
14
+ from typing import Dict, List, Optional, Any, Literal
15
+ import os
16
+
17
+
18
+ @dataclass
19
+ class NetworkRecipientConfig:
20
+ """
21
+ Configuration for a specific network's recipient address.
22
+
23
+ Use this to specify different recipient addresses for different networks.
24
+ """
25
+
26
+ recipient: str
27
+ enabled: bool = True
28
+
29
+
30
+ # Alias for backward compatibility
31
+ NetworkConfig = NetworkRecipientConfig
32
+
33
+
34
+ @dataclass
35
+ class MultiPaymentConfig:
36
+ """
37
+ Configuration for multi-payment support.
38
+
39
+ Allows users to offer multiple networks for payment acceptance.
40
+ """
41
+
42
+ networks: List[str] = field(default_factory=list)
43
+ default_network: Optional[str] = None
44
+
45
+ def __post_init__(self) -> None:
46
+ if self.networks and not self.default_network:
47
+ self.default_network = self.networks[0]
48
+
49
+
50
+ @dataclass
51
+ class X402Config:
52
+ """
53
+ Main SDK configuration.
54
+
55
+ Attributes:
56
+ facilitator_url: URL of the x402 facilitator service
57
+ recipient_evm: Default recipient address for EVM chains
58
+ recipient_solana: Recipient address for Solana/SVM chains (also used for Fogo)
59
+ recipient_near: Recipient account for NEAR
60
+ recipient_stellar: Recipient address for Stellar
61
+ facilitator_solana: Solana/SVM facilitator address (fee payer)
62
+ verify_timeout: Timeout for verify requests (seconds)
63
+ settle_timeout: Timeout for settle requests (seconds)
64
+ supported_networks: List of enabled network names
65
+ network_configs: Per-network recipient overrides
66
+ resource_url: Resource URL sent to facilitator
67
+ description: Description sent to facilitator
68
+ x402_version: Protocol version to use (1, 2, or "auto")
69
+ multi_payment: Multi-payment configuration for accepting multiple networks
70
+ """
71
+
72
+ facilitator_url: str = "https://facilitator.ultravioletadao.xyz"
73
+
74
+ # Recipient addresses per network type
75
+ recipient_evm: str = ""
76
+ recipient_solana: str = "" # Also used for Fogo and other SVM chains
77
+ recipient_near: str = ""
78
+ recipient_stellar: str = ""
79
+
80
+ # Solana/SVM facilitator (fee payer) - same for all SVM chains
81
+ facilitator_solana: str = "F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq"
82
+
83
+ # Timeouts
84
+ verify_timeout: float = 30.0
85
+ settle_timeout: float = 55.0 # Must be < Lambda timeout (60s)
86
+
87
+ # Network configuration - All 14 networks
88
+ supported_networks: List[str] = field(default_factory=lambda: [
89
+ # EVM chains (10)
90
+ "base", "ethereum", "polygon", "arbitrum", "optimism",
91
+ "avalanche", "celo", "hyperevm", "unichain", "monad",
92
+ # SVM chains (2)
93
+ "solana", "fogo",
94
+ # NEAR (1)
95
+ "near",
96
+ # Stellar (1)
97
+ "stellar",
98
+ ])
99
+
100
+ # Per-network recipient overrides
101
+ network_configs: Dict[str, NetworkRecipientConfig] = field(default_factory=dict)
102
+
103
+ # Facilitator request metadata
104
+ resource_url: str = ""
105
+ description: str = "x402 payment"
106
+
107
+ # x402 protocol version: 1, 2, or "auto" (detect from payload)
108
+ x402_version: Literal[1, 2, "auto"] = "auto"
109
+
110
+ # Multi-payment configuration
111
+ multi_payment: Optional[MultiPaymentConfig] = None
112
+
113
+ def __post_init__(self) -> None:
114
+ """Validate configuration after initialization."""
115
+ if not self.facilitator_url:
116
+ raise ValueError("facilitator_url is required")
117
+
118
+ # At least one recipient is required
119
+ if not any([
120
+ self.recipient_evm,
121
+ self.recipient_solana,
122
+ self.recipient_near,
123
+ self.recipient_stellar,
124
+ ]):
125
+ raise ValueError("At least one recipient address is required")
126
+
127
+ @classmethod
128
+ def from_env(cls) -> "X402Config":
129
+ """
130
+ Create configuration from environment variables.
131
+
132
+ Environment variables:
133
+ X402_FACILITATOR_URL: Facilitator URL
134
+ X402_RECIPIENT_EVM: EVM recipient address
135
+ X402_RECIPIENT_SOLANA: Solana recipient address
136
+ X402_RECIPIENT_NEAR: NEAR recipient account
137
+ X402_RECIPIENT_STELLAR: Stellar recipient address
138
+ X402_FACILITATOR_SOLANA: Solana fee payer address
139
+ X402_VERIFY_TIMEOUT: Verify request timeout
140
+ X402_SETTLE_TIMEOUT: Settle request timeout
141
+ X402_RESOURCE_URL: Resource URL for facilitator
142
+ X402_DESCRIPTION: Description for facilitator
143
+ """
144
+ return cls(
145
+ facilitator_url=os.environ.get(
146
+ "X402_FACILITATOR_URL",
147
+ "https://facilitator.ultravioletadao.xyz",
148
+ ),
149
+ recipient_evm=os.environ.get("X402_RECIPIENT_EVM", ""),
150
+ recipient_solana=os.environ.get("X402_RECIPIENT_SOLANA", ""),
151
+ recipient_near=os.environ.get("X402_RECIPIENT_NEAR", ""),
152
+ recipient_stellar=os.environ.get("X402_RECIPIENT_STELLAR", ""),
153
+ facilitator_solana=os.environ.get(
154
+ "X402_FACILITATOR_SOLANA",
155
+ "F742C4VfFLQ9zRQyithoj5229ZgtX2WqKCSFKgH2EThq",
156
+ ),
157
+ verify_timeout=float(os.environ.get("X402_VERIFY_TIMEOUT", "30")),
158
+ settle_timeout=float(os.environ.get("X402_SETTLE_TIMEOUT", "55")),
159
+ resource_url=os.environ.get("X402_RESOURCE_URL", ""),
160
+ description=os.environ.get("X402_DESCRIPTION", "x402 payment"),
161
+ )
162
+
163
+ def get_recipient(self, network: str) -> str:
164
+ """
165
+ Get recipient address for a specific network.
166
+
167
+ First checks network_configs for overrides, then falls back to
168
+ network-type default.
169
+
170
+ Args:
171
+ network: Network name (e.g., 'base', 'solana', 'fogo')
172
+
173
+ Returns:
174
+ Recipient address for the network
175
+ """
176
+ # Check for network-specific override
177
+ if network in self.network_configs:
178
+ return self.network_configs[network].recipient
179
+
180
+ # Fall back to network-type default
181
+ from uvd_x402_sdk.networks import get_network, NetworkType
182
+
183
+ network_config = get_network(network)
184
+ if not network_config:
185
+ return self.recipient_evm # Default to EVM
186
+
187
+ # SVM chains (Solana, Fogo, etc.) use the same recipient
188
+ if NetworkType.is_svm(network_config.network_type):
189
+ return self.recipient_solana
190
+ elif network_config.network_type == NetworkType.NEAR:
191
+ return self.recipient_near
192
+ elif network_config.network_type == NetworkType.STELLAR:
193
+ return self.recipient_stellar
194
+ else:
195
+ return self.recipient_evm
196
+
197
+ def is_network_enabled(self, network: str) -> bool:
198
+ """
199
+ Check if a network is enabled.
200
+
201
+ Args:
202
+ network: Network name
203
+
204
+ Returns:
205
+ True if network is in supported_networks and not disabled
206
+ """
207
+ if network not in self.supported_networks:
208
+ return False
209
+
210
+ # Check network-specific config
211
+ if network in self.network_configs:
212
+ return self.network_configs[network].enabled
213
+
214
+ return True
215
+
216
+ def get_supported_chain_ids(self) -> List[int]:
217
+ """
218
+ Get list of supported EVM chain IDs.
219
+
220
+ Returns:
221
+ List of chain IDs for enabled EVM networks
222
+ """
223
+ from uvd_x402_sdk.networks import get_network, NetworkType
224
+
225
+ chain_ids = []
226
+ for network_name in self.supported_networks:
227
+ network = get_network(network_name)
228
+ if network and network.network_type == NetworkType.EVM and network.chain_id > 0:
229
+ if self.is_network_enabled(network_name):
230
+ chain_ids.append(network.chain_id)
231
+
232
+ return chain_ids
233
+
234
+ def to_dict(self) -> Dict[str, Any]:
235
+ """Convert configuration to dictionary."""
236
+ return {
237
+ "facilitator_url": self.facilitator_url,
238
+ "recipient_evm": self.recipient_evm,
239
+ "recipient_solana": self.recipient_solana,
240
+ "recipient_near": self.recipient_near,
241
+ "recipient_stellar": self.recipient_stellar,
242
+ "facilitator_solana": self.facilitator_solana,
243
+ "verify_timeout": self.verify_timeout,
244
+ "settle_timeout": self.settle_timeout,
245
+ "supported_networks": self.supported_networks,
246
+ "resource_url": self.resource_url,
247
+ "description": self.description,
248
+ }