swapzone 0.1.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.
swapzone/__init__.py ADDED
@@ -0,0 +1,23 @@
1
+ """Swapzone cryptocurrency exchange and DEX aggregator client."""
2
+
3
+ from .client import Swapzone
4
+ from .errors import SwapzoneError
5
+ from .types import (
6
+ DEXBlockchain,
7
+ RateOffer,
8
+ SupportedCurrency,
9
+ TransactionResult,
10
+ TransactionStatus,
11
+ ValidateAddressResult,
12
+ )
13
+
14
+ __all__ = [
15
+ "DEXBlockchain",
16
+ "RateOffer",
17
+ "SupportedCurrency",
18
+ "Swapzone",
19
+ "SwapzoneError",
20
+ "TransactionResult",
21
+ "TransactionStatus",
22
+ "ValidateAddressResult",
23
+ ]
swapzone/client.py ADDED
@@ -0,0 +1,341 @@
1
+ import os
2
+ from typing import Any
3
+
4
+ import httpx
5
+
6
+ from .errors import SwapzoneError
7
+ from .types import (
8
+ DEXBlockchain,
9
+ RateOffer,
10
+ SupportedCurrency,
11
+ TransactionResult,
12
+ TransactionStatus,
13
+ ValidateAddressResult,
14
+ )
15
+
16
+
17
+ class Swapzone:
18
+ """Client for the Swapzone cryptocurrency exchange and DEX aggregator API.
19
+
20
+ Attributes:
21
+ api_key: Swapzone API key.
22
+ base_url: Base URL of the API.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ api_key: str | None = None,
28
+ base_url: str | None = None,
29
+ timeout: float = 30.0,
30
+ user_agent: str | None = None,
31
+ ) -> None:
32
+ """Initializes the Swapzone client.
33
+
34
+ Args:
35
+ api_key: Swapzone API key. Defaults to SWAPZONE_API_KEY environment variable.
36
+ base_url: Base URL for the Swapzone API. Defaults to https://api.swapzone.io.
37
+ timeout: Timeout in seconds for HTTP requests. Defaults to 30.0.
38
+ user_agent: Custom User-Agent header string.
39
+
40
+ Examples:
41
+ >>> from swapzone import Swapzone
42
+ >>> client = Swapzone(api_key="your-api-key")
43
+ >>> currencies = client.get_currencies()
44
+ >>> print(len(currencies))
45
+ """
46
+ self.api_key = api_key or os.environ.get("SWAPZONE_API_KEY")
47
+ self.base_url = (base_url or "https://api.swapzone.io").rstrip("/")
48
+ ua = user_agent or "swapzone-client/0.1.0"
49
+
50
+ headers: dict[str, str] = {
51
+ "User-Agent": ua,
52
+ "Accept": "application/json",
53
+ "Content-Type": "application/json",
54
+ }
55
+ if self.api_key:
56
+ headers["x-api-key"] = self.api_key
57
+
58
+ self._client = httpx.Client(
59
+ base_url=self.base_url,
60
+ timeout=timeout,
61
+ headers=headers,
62
+ )
63
+
64
+ def close(self) -> None:
65
+ """Closes the underlying HTTP client session."""
66
+ self._client.close()
67
+
68
+ def __enter__(self) -> "Swapzone":
69
+ return self
70
+
71
+ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
72
+ self.close()
73
+
74
+ def _request(
75
+ self,
76
+ method: str,
77
+ path: str,
78
+ params: dict[str, Any] | None = None,
79
+ json_data: dict[str, Any] | None = None,
80
+ ) -> Any:
81
+ try:
82
+ response = self._client.request(
83
+ method,
84
+ path,
85
+ params=params,
86
+ json=json_data,
87
+ )
88
+ response.raise_for_status()
89
+ data = response.json()
90
+
91
+ if isinstance(data, dict) and data.get("error") is True:
92
+ msg = data.get("message") or "Swapzone API error"
93
+ raise SwapzoneError(
94
+ message=str(msg),
95
+ status_code=response.status_code,
96
+ response_body=data,
97
+ )
98
+
99
+ return data
100
+ except httpx.HTTPStatusError as e:
101
+ try:
102
+ data_err = e.response.json()
103
+ except Exception:
104
+ data_err = None
105
+ msg = "Swapzone API error"
106
+ if isinstance(data_err, dict) and data_err.get("message"):
107
+ msg = str(data_err["message"])
108
+ raise SwapzoneError(
109
+ message=msg,
110
+ status_code=e.response.status_code,
111
+ response_body=data_err,
112
+ ) from e
113
+ except httpx.RequestError as e:
114
+ raise SwapzoneError(f"HTTP request failed: {e}") from e
115
+
116
+ def get_currencies(self) -> list[SupportedCurrency]:
117
+ """Retrieves all supported cryptocurrencies and tokens.
118
+
119
+ Returns:
120
+ List of supported currencies with tickers and networks.
121
+
122
+ Examples:
123
+ >>> currencies = client.get_currencies()
124
+ >>> print(currencies[0]["ticker"])
125
+ """
126
+ return self._request("GET", "/v1/exchange/currencies")
127
+
128
+ def get_rate(
129
+ self,
130
+ from_currency: str,
131
+ to_currency: str,
132
+ amount: float | str,
133
+ rate_type: str = "all",
134
+ choose_rate: str = "best",
135
+ available_in_usa: bool | None = None,
136
+ no_refund_address: bool | None = None,
137
+ from_network: str | None = None,
138
+ to_network: str | None = None,
139
+ amount_to: float | str | None = None,
140
+ timeout: float | str | None = None,
141
+ ) -> RateOffer:
142
+ """Retrieves rate estimates for an exchange pair.
143
+
144
+ Args:
145
+ from_currency: Deposit asset ticker (e.g. 'btc').
146
+ to_currency: Receiving asset ticker (e.g. 'eth').
147
+ amount: Deposit amount.
148
+ rate_type: Rate type ('all', 'fixed', or 'floating').
149
+ choose_rate: Strategy ('best', 'all', or 'recommended').
150
+ available_in_usa: Restrict to partners supporting US clients.
151
+ no_refund_address: Restrict to exchangers with optional refund address.
152
+ from_network: Network for deposit asset.
153
+ to_network: Network for receiving asset.
154
+ amount_to: Target receiving amount (for reverse rate).
155
+ timeout: Maximum response timeout in ms.
156
+
157
+ Returns:
158
+ Rate offer dictionary with amounts and quota ID.
159
+
160
+ Examples:
161
+ >>> rate = client.get_rate("btc", "eth", amount="0.1")
162
+ >>> print(f"ETH: {rate['amountTo']} via {rate['adapter']}")
163
+ """
164
+ params: dict[str, Any] = {
165
+ "from": from_currency,
166
+ "to": to_currency,
167
+ "amount": str(amount),
168
+ "rateType": rate_type,
169
+ "chooseRate": choose_rate,
170
+ }
171
+ if available_in_usa is not None:
172
+ params["availableInUSA"] = available_in_usa
173
+ if no_refund_address is not None:
174
+ params["noRefundAddress"] = no_refund_address
175
+ if from_network is not None:
176
+ params["fromNetwork"] = from_network
177
+ if to_network is not None:
178
+ params["toNetwork"] = to_network
179
+ if amount_to is not None:
180
+ params["amountTo"] = str(amount_to)
181
+ if timeout is not None:
182
+ params["timeout"] = str(timeout)
183
+
184
+ return self._request("GET", "/v1/exchange/get-rate", params=params)
185
+
186
+ def create_transaction(
187
+ self,
188
+ from_currency: str,
189
+ to_currency: str,
190
+ amount_deposit: float | str,
191
+ address_receive: str,
192
+ extra_id_receive: str | None = None,
193
+ refund_address: str | None = None,
194
+ refund_extra_id: str | None = None,
195
+ quota_id: str | None = None,
196
+ no_quota_id: bool | None = None,
197
+ from_network: str | None = None,
198
+ to_network: str | None = None,
199
+ offer_reference_id: str | None = None,
200
+ ) -> TransactionResult:
201
+ """Creates an exchange transaction order.
202
+
203
+ Args:
204
+ from_currency: Deposit asset ticker.
205
+ to_currency: Receiving asset ticker.
206
+ amount_deposit: Amount to deposit.
207
+ address_receive: Destination recipient wallet address.
208
+ extra_id_receive: Optional memo / extra ID for recipient.
209
+ refund_address: Optional address to return funds on failure.
210
+ refund_extra_id: Optional memo for refund address.
211
+ quota_id: Quota ID obtained from get_rate.
212
+ no_quota_id: Bypass quota ID requirement.
213
+ from_network: Deposit blockchain network.
214
+ to_network: Receiving blockchain network.
215
+ offer_reference_id: Reference ID for fixed-rate quotes.
216
+
217
+ Returns:
218
+ Order details containing deposit address and transaction ID.
219
+
220
+ Examples:
221
+ >>> order = client.create_transaction(
222
+ ... from_currency="btc",
223
+ ... to_currency="eth",
224
+ ... amount_deposit="0.1",
225
+ ... address_receive="0xReceiverAddress...",
226
+ ... quota_id=rate["quotaId"],
227
+ ... )
228
+ >>> print(f"Deposit address: {order['addressDeposit']}")
229
+ """
230
+ payload: dict[str, Any] = {
231
+ "from": from_currency,
232
+ "to": to_currency,
233
+ "amountDeposit": str(amount_deposit),
234
+ "addressReceive": address_receive,
235
+ }
236
+ if extra_id_receive is not None:
237
+ payload["extraIdReceive"] = extra_id_receive
238
+ if refund_address is not None:
239
+ payload["refundAddress"] = refund_address
240
+ if refund_extra_id is not None:
241
+ payload["refundExtraId"] = refund_extra_id
242
+ if quota_id is not None:
243
+ payload["quotaId"] = quota_id
244
+ if no_quota_id is not None:
245
+ payload["noQuotaId"] = no_quota_id
246
+ if from_network is not None:
247
+ payload["fromNetwork"] = from_network
248
+ if to_network is not None:
249
+ payload["toNetwork"] = to_network
250
+ if offer_reference_id is not None:
251
+ payload["offerReferenceId"] = offer_reference_id
252
+
253
+ return self._request("POST", "/v1/exchange/create", json_data=payload)
254
+
255
+ def get_transaction(self, transaction_id: str) -> TransactionStatus:
256
+ """Retrieves transaction status.
257
+
258
+ Args:
259
+ transaction_id: Swapzone transaction ID.
260
+
261
+ Returns:
262
+ Transaction details and status.
263
+
264
+ Examples:
265
+ >>> status = client.get_transaction("tx-id")
266
+ >>> print(status["status"])
267
+ """
268
+ return self._request("GET", "/v1/exchange/tx", params={"id": transaction_id})
269
+
270
+ def validate_address(
271
+ self,
272
+ currency: str,
273
+ address: str,
274
+ network: str | None = None,
275
+ ) -> ValidateAddressResult:
276
+ """Validates a cryptocurrency address for a given asset.
277
+
278
+ Args:
279
+ currency: Asset ticker (e.g. 'eth').
280
+ address: Wallet address to validate.
281
+ network: Blockchain network (e.g. 'ETH').
282
+
283
+ Returns:
284
+ Dictionary indicating if the address is valid.
285
+
286
+ Examples:
287
+ >>> res = client.validate_address("eth", "0x57f3...", network="ETH")
288
+ >>> print(res["result"])
289
+ """
290
+ params: dict[str, Any] = {
291
+ "currency": currency,
292
+ "address": address,
293
+ }
294
+ if network is not None:
295
+ params["network"] = network
296
+
297
+ return self._request("GET", "/v1/exchange/validate/address", params=params)
298
+
299
+ def get_markets(self, rate_type: str | None = None) -> list[Any]:
300
+ """Retrieves bulk rate markets for instant exchange pairs.
301
+
302
+ Args:
303
+ rate_type: Optional rate type filter ('all', 'fixed', 'floating').
304
+
305
+ Returns:
306
+ List of market pairs.
307
+
308
+ Examples:
309
+ >>> markets = client.get_markets("fixed")
310
+ """
311
+ params = {"rateType": rate_type} if rate_type else None
312
+ return self._request("GET", "/v1/exchange/markets", params=params)
313
+
314
+ def get_dex_blockchains(self) -> list[DEXBlockchain]:
315
+ """Retrieves supported blockchain networks for decentralized swaps.
316
+
317
+ Returns:
318
+ List of supported blockchains with chain IDs.
319
+
320
+ Examples:
321
+ >>> chains = client.get_dex_blockchains()
322
+ >>> print(len(chains))
323
+ """
324
+ res = self._request("GET", "/v1/dex/blockchains")
325
+ if isinstance(res, dict) and "result" in res:
326
+ return res["result"]
327
+ return res
328
+
329
+ def get_dex_tokens(self) -> list[Any]:
330
+ """Retrieves supported tokens for DEX swaps.
331
+
332
+ Returns:
333
+ List of supported tokens.
334
+
335
+ Examples:
336
+ >>> tokens = client.get_dex_tokens()
337
+ """
338
+ res = self._request("GET", "/v1/dex/tokens")
339
+ if isinstance(res, dict) and "result" in res:
340
+ return res["result"]
341
+ return res
swapzone/errors.py ADDED
@@ -0,0 +1,21 @@
1
+ from typing import Any
2
+
3
+
4
+ class SwapzoneError(Exception):
5
+ """Exception raised when a Swapzone API call fails."""
6
+
7
+ def __init__(
8
+ self,
9
+ message: str,
10
+ status_code: int | None = None,
11
+ response_body: Any = None,
12
+ ) -> None:
13
+ super().__init__(message)
14
+ self.message = message
15
+ self.status_code = status_code
16
+ self.response_body = response_body
17
+
18
+ def __str__(self) -> str:
19
+ if self.status_code is not None:
20
+ return f"[{self.status_code}] {self.message}"
21
+ return self.message
swapzone/types.py ADDED
@@ -0,0 +1,71 @@
1
+ from typing import Any
2
+
3
+ from typing_extensions import TypedDict
4
+
5
+
6
+ class SupportedCurrency(TypedDict, total=False):
7
+ name: str
8
+ ticker: str
9
+ network: str
10
+ defaultAmount: float
11
+ smartContract: str | None
12
+ alias: list[str]
13
+ hasExternalId: bool
14
+
15
+
16
+ class RateOffer(TypedDict, total=False):
17
+ adapter: str
18
+ from_: str
19
+ fromNetwork: str
20
+ to: str
21
+ toNetwork: str
22
+ amountFrom: float
23
+ amountTo: float
24
+ amountFromUSD: float
25
+ amountToUSD: float
26
+ quotaId: str
27
+ minAmount: float
28
+ maxAmount: float
29
+ time: int
30
+ accuracyRate: float
31
+
32
+
33
+ class TransactionResult(TypedDict, total=False):
34
+ id: str
35
+ quotaId: str
36
+ status: str
37
+ addressReceive: str
38
+ addressDeposit: str
39
+ extraIdReceive: str
40
+ amountDeposit: float
41
+ amountEstimated: float
42
+ createdAt: str
43
+ refundAddress: str
44
+ refundExtraId: str
45
+ payTill: str
46
+
47
+
48
+ class TransactionStatus(TypedDict, total=False):
49
+ id: str
50
+ status: str
51
+ amountDeposit: float
52
+ amountEstimated: float
53
+ addressDeposit: str
54
+ addressReceive: str
55
+ hashDeposit: str | None
56
+ hashReceive: str | None
57
+ createdAt: str
58
+ updatedAt: str
59
+
60
+
61
+ class ValidateAddressResult(TypedDict, total=False):
62
+ result: bool
63
+ message: str | None
64
+
65
+
66
+ class DEXBlockchain(TypedDict, total=False):
67
+ chainId: int
68
+ name: str
69
+ nativeCurrency: dict[str, Any]
70
+ rpcUrls: list[str]
71
+ explorerUrls: list[str]
@@ -0,0 +1,198 @@
1
+ Metadata-Version: 2.5
2
+ Name: swapzone
3
+ Version: 0.1.0
4
+ Summary: Python client for the Swapzone cryptocurrency exchange and DEX aggregator API
5
+ Project-URL: Repository, https://github.com/TysikGG/api-kit
6
+ Project-URL: Documentation, https://documenter.getpostman.com/view/16362858/UVXokDS6
7
+ License-Expression: ISC
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: httpx>=0.27
11
+ Description-Content-Type: text/markdown
12
+
13
+ # swapzone
14
+
15
+ [![PyPI version](https://img.shields.io/pypi/v/swapzone.svg)](https://pypi.org/project/swapzone/)
16
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
17
+ [![Python Version](https://img.shields.io/pypi/pyversions/swapzone.svg)](https://pypi.org/project/swapzone/)
18
+
19
+ Modern, fully typed Python client library for the [Swapzone](https://swapzone.io) instant cryptocurrency exchange & DEX cross-chain aggregator REST API.
20
+
21
+ Official API documentation: <https://documenter.getpostman.com/view/16362858/UVXokDS6>
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - 🔄 **15+ Exchange Providers Aggregated** — Compares rates in real time across top instant swap platforms (SimpleSwap, StealthEX, ChangeNOW, Changelly, etc.).
28
+ - 🪙 **1000+ Cryptocurrencies** — Full support for fixed and floating cross-chain swaps.
29
+ - 🐍 **Modern Pythonic Design** — Type annotations, dataclass models (`RateOffer`, `TransactionResult`, `SupportedCurrency`, `TransactionStatus`), context manager support (`with Swapzone(...) as client:`), and custom exceptions.
30
+ - ⚡ **DEX Aggregation** — DEX blockchain routes, token catalogs, and quote comparisons.
31
+ - 🛡️ **Address Validation** — Built-in `validate_address()` helper to verify destination wallet addresses.
32
+
33
+ ---
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install swapzone
39
+ ```
40
+
41
+ Requires Python 3.10 or higher.
42
+
43
+ ---
44
+
45
+ ## Quick Start (Safe Check)
46
+
47
+ The quick check only inspects supported currencies and compares live provider exchange rates. It does not create orders:
48
+
49
+ ```python
50
+ import os
51
+ from swapzone import Swapzone
52
+
53
+ with Swapzone(api_key=os.environ["SWAPZONE_API_KEY"]) as client:
54
+ # 1. Fetch supported currencies
55
+ currencies = client.get_currencies()
56
+ print(f"Available currencies: {len(currencies)}")
57
+
58
+ # 2. Query best rate offer for 0.1 BTC to ETH
59
+ rate = client.get_rate(
60
+ from_currency="btc",
61
+ to_currency="eth",
62
+ amount=0.1,
63
+ rate_type="all",
64
+ )
65
+ print(f"Best Provider: {rate.best_offer.adapter}")
66
+ print(f"Estimated Receive: {rate.best_offer.amount_to} ETH")
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Usage Guide
72
+
73
+ ### 1. Finding the Best Rate and Creating a Swap
74
+
75
+ Full lifecycle: query provider rates, validate destination address, create transaction, and monitor status:
76
+
77
+ ```python
78
+ from swapzone import Swapzone, SwapzoneError
79
+
80
+ with Swapzone(api_key="your_api_key") as client:
81
+ # 1. Get rate offers across all providers
82
+ rate = client.get_rate(
83
+ from_currency="btc",
84
+ to_currency="eth",
85
+ amount=0.1,
86
+ rate_type="all",
87
+ )
88
+ best_offer = rate.best_offer
89
+ print(f"Selected Provider: {best_offer.adapter} (Quota: {best_offer.amount_to} ETH)")
90
+
91
+ # 2. Validate destination wallet address
92
+ check = client.validate_address(
93
+ currency="eth",
94
+ address="0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
95
+ )
96
+ if not check.result:
97
+ raise ValueError("Invalid destination wallet address!")
98
+
99
+ # 3. Create transaction with the selected provider
100
+ tx = client.create_transaction(
101
+ from_currency="btc",
102
+ to_currency="eth",
103
+ amount_deposit=0.1,
104
+ address_receive="0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
105
+ quota_id=best_offer.quota_id,
106
+ refund_address="bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", # optional
107
+ )
108
+
109
+ print(f"Transaction Created! ID: {tx.transaction.id}")
110
+ print(f"Send BTC to Deposit Address: {tx.transaction.address_deposit}")
111
+ print(f"Status: {tx.transaction.status}")
112
+ ```
113
+
114
+ ### 2. Tracking Transaction Progress
115
+
116
+ Monitor swap progress from deposit to settlement:
117
+
118
+ ```python
119
+ current = client.get_transaction(tx.transaction.id)
120
+ print(f"Status: {current.status}")
121
+
122
+ if current.status == "finished":
123
+ print(f"Received: {current.amount_receive} ETH")
124
+ ```
125
+
126
+ ### 3. Querying DEX Aggregation
127
+
128
+ Inspect supported DEX blockchains and token pairs:
129
+
130
+ ```python
131
+ # List supported DEX blockchains
132
+ blockchains = client.get_dex_blockchains()
133
+ print("DEX Blockchains:", blockchains)
134
+
135
+ # Check DEX tokens
136
+ dex_tokens = client.get_dex_tokens()
137
+ print(f"DEX Tokens count: {len(dex_tokens)}")
138
+ ```
139
+
140
+ ---
141
+
142
+ ## API Reference
143
+
144
+ ### `Swapzone` Class
145
+
146
+ #### Constructor
147
+
148
+ ```python
149
+ Swapzone(
150
+ api_key: str,
151
+ base_url: str = "https://api.swapzone.io/v1",
152
+ timeout: float = 30.0,
153
+ )
154
+ ```
155
+
156
+ | Parameter | Type | Default | Description |
157
+ | :--- | :--- | :--- | :--- |
158
+ | `api_key` | `str` | **Required** | Your Swapzone API key. |
159
+ | `base_url` | `str` | `"https://api.swapzone.io/v1"` | Swapzone API base URL. |
160
+ | `timeout` | `float` | `30.0` | HTTP request timeout in seconds. |
161
+
162
+ #### Methods
163
+
164
+ - **`get_currencies() -> list[SupportedCurrency]`** — Returns all supported cryptocurrencies.
165
+ - **`get_rate(from_currency, to_currency, amount, rate_type="all") -> RateOffer`** — Returns aggregated quotes.
166
+ - **`create_transaction(from_currency, to_currency, amount_deposit, address_receive, quota_id, ...) -> TransactionResult`** — Creates transaction.
167
+ - **`get_transaction(transaction_id: str) -> TransactionStatus`** — Checks swap status and execution details.
168
+ - **`validate_address(currency, address) -> ValidateAddressResult`** — Validates destination wallet address.
169
+ - **`get_markets(rate_type=None) -> list[Any]`** — Retrieves active market pairs.
170
+ - **`get_dex_blockchains() -> list[DEXBlockchain]`** — Lists supported DEX blockchains.
171
+ - **`get_dex_tokens() -> list[Any]`** — Lists tokens supported on DEX routers.
172
+
173
+ ---
174
+
175
+ ## Error Handling
176
+
177
+ When the API returns an error, `SwapzoneError` is raised:
178
+
179
+ ```python
180
+ from swapzone import Swapzone, SwapzoneError
181
+
182
+ try:
183
+ with Swapzone(api_key="invalid_key") as client:
184
+ client.get_currencies()
185
+ except SwapzoneError as exc:
186
+ print(f"Swapzone Error: {exc.message} (Status: {exc.status})")
187
+ ```
188
+
189
+ Common HTTP status codes:
190
+ - `400 Bad Request` — Invalid address or amount out of limits.
191
+ - `401 Unauthorized` — Invalid API key.
192
+ - `404 Not Found` — Transaction ID not found.
193
+
194
+ ---
195
+
196
+ ## License
197
+
198
+ ISC
@@ -0,0 +1,8 @@
1
+ swapzone/__init__.py,sha256=EeGsFbxT6hdtwVbVFbiZd6dx4yVLK4mDPDh4HgLsQiU,477
2
+ swapzone/client.py,sha256=O95Pnqo8H2gululdU-vH0FrZPmeagDHLFRw-xL3Scls,11677
3
+ swapzone/errors.py,sha256=L9Kt1Qq__Kp2NzbcAhWtQOfbRetq_HnWQMrrAH8akW4,566
4
+ swapzone/types.py,sha256=KTygOSJLN3tYk2x7lfQtv7e0lu9q8MGSgAqDibG47P4,1411
5
+ swapzone-0.1.0.dist-info/METADATA,sha256=A3S6sIU96Z8vQH2z8f41PzSqwSZu4FeQIw9FgM0srnE,6343
6
+ swapzone-0.1.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
7
+ swapzone-0.1.0.dist-info/licenses/LICENSE,sha256=8S0uYmn_aeljwFudfBoV91HcIo79yab9s0yhMVsOHJ0,751
8
+ swapzone-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 api-kit contributors
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.