cryptonly-x402 0.1.0__tar.gz

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.
@@ -0,0 +1,74 @@
1
+ Metadata-Version: 2.4
2
+ Name: cryptonly-x402
3
+ Version: 0.1.0
4
+ Summary: Cryptonly facilitator client for the x402 payment protocol.
5
+ Author-email: Cryptonly <noreply@cryptonly.net>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/cryptonly-net/x402/tree/main/python
8
+ Project-URL: Documentation, https://cryptonly.gitbook.io/docs
9
+ Project-URL: Repository, https://github.com/cryptonly-net/x402
10
+ Project-URL: Issues, https://github.com/cryptonly-net/x402/issues
11
+ Keywords: cryptonly,x402,facilitator,payments,client,python
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: x402>=2
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8; extra == "dev"
19
+
20
+ <img src="https://raw.githubusercontent.com/cryptonly-net/.github/main/profile/assets/header-banner.svg" alt="Cryptonly" width="100%" />
21
+
22
+ <div align="center">
23
+
24
+ # Cryptonly — x402 facilitator
25
+
26
+ Facilitator client for x402 payments.
27
+
28
+ [Website](https://cryptonly.net) · [Documentation](https://cryptonly.gitbook.io/docs) · [Contact](https://cryptonly.net/contact/)
29
+
30
+ </div>
31
+
32
+ ---
33
+
34
+ Pass the async client to `x402ResourceServer` for FastAPI. Pass the sync client to `x402ResourceServerSync` for Flask.
35
+
36
+ ```bash
37
+ pip install cryptonly-x402 "x402[fastapi,evm]"
38
+ ```
39
+
40
+ `x402` >=2 is a dependency. Install the extra for the framework and chain you use, such as `x402[fastapi,evm]` or `x402[flask,evm]`.
41
+
42
+ ```python
43
+ import os
44
+
45
+ from cryptonly_x402 import CryptonlyFacilitatorClient
46
+ from x402.mechanisms.evm.exact import ExactEvmServerScheme
47
+ from x402.server import x402ResourceServer
48
+
49
+ facilitator = CryptonlyFacilitatorClient(os.environ["CRYPTONLY_API_KEY"])
50
+
51
+ server = x402ResourceServer(facilitator)
52
+ server.register("eip155:8453", ExactEvmServerScheme())
53
+ ```
54
+
55
+ `api_key` is your Cryptonly API key. It is sent as `x-tenant-api-key` on verify, settle, and supported.
56
+
57
+ ```python
58
+ facilitator = CryptonlyFacilitatorClient(os.environ["CRYPTONLY_API_KEY"])
59
+ ```
60
+
61
+ Flask uses the sync client:
62
+
63
+ ```python
64
+ from cryptonly_x402 import CryptonlyFacilitatorClientSync
65
+ from x402.mechanisms.evm.exact import ExactEvmServerScheme
66
+ from x402.server import x402ResourceServerSync
67
+
68
+ facilitator = CryptonlyFacilitatorClientSync(os.environ["CRYPTONLY_API_KEY"])
69
+
70
+ server = x402ResourceServerSync(facilitator)
71
+ server.register("eip155:8453", ExactEvmServerScheme())
72
+ ```
73
+
74
+ Set `sandbox=True` to use the sandbox facilitator with testnest.
@@ -0,0 +1,55 @@
1
+ <img src="https://raw.githubusercontent.com/cryptonly-net/.github/main/profile/assets/header-banner.svg" alt="Cryptonly" width="100%" />
2
+
3
+ <div align="center">
4
+
5
+ # Cryptonly — x402 facilitator
6
+
7
+ Facilitator client for x402 payments.
8
+
9
+ [Website](https://cryptonly.net) · [Documentation](https://cryptonly.gitbook.io/docs) · [Contact](https://cryptonly.net/contact/)
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ Pass the async client to `x402ResourceServer` for FastAPI. Pass the sync client to `x402ResourceServerSync` for Flask.
16
+
17
+ ```bash
18
+ pip install cryptonly-x402 "x402[fastapi,evm]"
19
+ ```
20
+
21
+ `x402` >=2 is a dependency. Install the extra for the framework and chain you use, such as `x402[fastapi,evm]` or `x402[flask,evm]`.
22
+
23
+ ```python
24
+ import os
25
+
26
+ from cryptonly_x402 import CryptonlyFacilitatorClient
27
+ from x402.mechanisms.evm.exact import ExactEvmServerScheme
28
+ from x402.server import x402ResourceServer
29
+
30
+ facilitator = CryptonlyFacilitatorClient(os.environ["CRYPTONLY_API_KEY"])
31
+
32
+ server = x402ResourceServer(facilitator)
33
+ server.register("eip155:8453", ExactEvmServerScheme())
34
+ ```
35
+
36
+ `api_key` is your Cryptonly API key. It is sent as `x-tenant-api-key` on verify, settle, and supported.
37
+
38
+ ```python
39
+ facilitator = CryptonlyFacilitatorClient(os.environ["CRYPTONLY_API_KEY"])
40
+ ```
41
+
42
+ Flask uses the sync client:
43
+
44
+ ```python
45
+ from cryptonly_x402 import CryptonlyFacilitatorClientSync
46
+ from x402.mechanisms.evm.exact import ExactEvmServerScheme
47
+ from x402.server import x402ResourceServerSync
48
+
49
+ facilitator = CryptonlyFacilitatorClientSync(os.environ["CRYPTONLY_API_KEY"])
50
+
51
+ server = x402ResourceServerSync(facilitator)
52
+ server.register("eip155:8453", ExactEvmServerScheme())
53
+ ```
54
+
55
+ Set `sandbox=True` to use the sandbox facilitator with testnest.
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cryptonly-x402"
7
+ version = "0.1.0"
8
+ description = "Cryptonly facilitator client for the x402 payment protocol."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ keywords = ["cryptonly", "x402", "facilitator", "payments", "client", "python"]
13
+ authors = [{ name = "Cryptonly", email = "noreply@cryptonly.net" }]
14
+ dependencies = ["x402>=2"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+
20
+ [project.optional-dependencies]
21
+ dev = ["pytest>=8"]
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/cryptonly-net/x402/tree/main/python"
25
+ Documentation = "https://cryptonly.gitbook.io/docs"
26
+ Repository = "https://github.com/cryptonly-net/x402"
27
+ Issues = "https://github.com/cryptonly-net/x402/issues"
28
+
29
+ [tool.setuptools.packages.find]
30
+ where = ["src"]
31
+
32
+ [tool.setuptools.package-data]
33
+ cryptonly_x402 = ["py.typed"]
34
+
35
+ [tool.pytest.ini_options]
36
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,16 @@
1
+ """Cryptonly facilitator client for the x402 payment protocol."""
2
+
3
+ from .client import CryptonlyFacilitatorClient, CryptonlyFacilitatorClientSync
4
+ from .constants import (
5
+ MERCHANT_API_BASE_URL,
6
+ MERCHANT_API_KEY_HEADER,
7
+ SANDBOX_MERCHANT_API_BASE_URL,
8
+ )
9
+
10
+ __all__ = [
11
+ "CryptonlyFacilitatorClient",
12
+ "CryptonlyFacilitatorClientSync",
13
+ "MERCHANT_API_BASE_URL",
14
+ "MERCHANT_API_KEY_HEADER",
15
+ "SANDBOX_MERCHANT_API_BASE_URL",
16
+ ]
@@ -0,0 +1,70 @@
1
+ """Cryptonly facilitator clients for the x402 protocol."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from x402.http import (
6
+ FacilitatorConfig,
7
+ HTTPFacilitatorClient,
8
+ HTTPFacilitatorClientSync,
9
+ )
10
+ from x402.http.facilitator_client_base import AuthHeaders
11
+
12
+ from .constants import (
13
+ MERCHANT_API_BASE_URL,
14
+ MERCHANT_API_KEY_HEADER,
15
+ SANDBOX_MERCHANT_API_BASE_URL,
16
+ )
17
+
18
+
19
+ class _ApiKeyAuth:
20
+ """Sends the Cryptonly API key on verify, settle, and supported."""
21
+
22
+ def __init__(self, api_key: str) -> None:
23
+ self._headers = {MERCHANT_API_KEY_HEADER: api_key}
24
+
25
+ def get_auth_headers(self) -> AuthHeaders:
26
+ headers = dict(self._headers)
27
+ return AuthHeaders(verify=headers, settle=dict(headers), supported=dict(headers))
28
+
29
+
30
+ def _resolve_facilitator_url(sandbox: bool) -> str:
31
+ origin = SANDBOX_MERCHANT_API_BASE_URL if sandbox else MERCHANT_API_BASE_URL
32
+ return f"{origin}/x402"
33
+
34
+
35
+ def _require_api_key(api_key: str, client_name: str) -> str:
36
+ if not api_key:
37
+ raise TypeError(f"{client_name}: api_key is required")
38
+ return api_key
39
+
40
+
41
+ class CryptonlyFacilitatorClient(HTTPFacilitatorClient):
42
+ """Async Cryptonly facilitator client.
43
+
44
+ Pass it to ``x402ResourceServer`` for FastAPI and other async servers.
45
+ """
46
+
47
+ def __init__(self, api_key: str, *, sandbox: bool = False) -> None:
48
+ key = _require_api_key(api_key, "CryptonlyFacilitatorClient")
49
+ super().__init__(
50
+ FacilitatorConfig(
51
+ url=_resolve_facilitator_url(sandbox),
52
+ auth_provider=_ApiKeyAuth(key),
53
+ )
54
+ )
55
+
56
+
57
+ class CryptonlyFacilitatorClientSync(HTTPFacilitatorClientSync):
58
+ """Sync Cryptonly facilitator client.
59
+
60
+ Pass it to ``x402ResourceServerSync`` for Flask and other sync servers.
61
+ """
62
+
63
+ def __init__(self, api_key: str, *, sandbox: bool = False) -> None:
64
+ key = _require_api_key(api_key, "CryptonlyFacilitatorClientSync")
65
+ super().__init__(
66
+ FacilitatorConfig(
67
+ url=_resolve_facilitator_url(sandbox),
68
+ auth_provider=_ApiKeyAuth(key),
69
+ )
70
+ )
@@ -0,0 +1,5 @@
1
+ """Cryptonly merchant API origins and the tenant API key header."""
2
+
3
+ MERCHANT_API_BASE_URL = "https://api-merchant.cryptonly.net"
4
+ SANDBOX_MERCHANT_API_BASE_URL = "https://sandbox-api-merchant.cryptonly.net"
5
+ MERCHANT_API_KEY_HEADER = "x-tenant-api-key"
File without changes
@@ -0,0 +1,74 @@
1
+ Metadata-Version: 2.4
2
+ Name: cryptonly-x402
3
+ Version: 0.1.0
4
+ Summary: Cryptonly facilitator client for the x402 payment protocol.
5
+ Author-email: Cryptonly <noreply@cryptonly.net>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/cryptonly-net/x402/tree/main/python
8
+ Project-URL: Documentation, https://cryptonly.gitbook.io/docs
9
+ Project-URL: Repository, https://github.com/cryptonly-net/x402
10
+ Project-URL: Issues, https://github.com/cryptonly-net/x402/issues
11
+ Keywords: cryptonly,x402,facilitator,payments,client,python
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ Requires-Dist: x402>=2
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest>=8; extra == "dev"
19
+
20
+ <img src="https://raw.githubusercontent.com/cryptonly-net/.github/main/profile/assets/header-banner.svg" alt="Cryptonly" width="100%" />
21
+
22
+ <div align="center">
23
+
24
+ # Cryptonly — x402 facilitator
25
+
26
+ Facilitator client for x402 payments.
27
+
28
+ [Website](https://cryptonly.net) · [Documentation](https://cryptonly.gitbook.io/docs) · [Contact](https://cryptonly.net/contact/)
29
+
30
+ </div>
31
+
32
+ ---
33
+
34
+ Pass the async client to `x402ResourceServer` for FastAPI. Pass the sync client to `x402ResourceServerSync` for Flask.
35
+
36
+ ```bash
37
+ pip install cryptonly-x402 "x402[fastapi,evm]"
38
+ ```
39
+
40
+ `x402` >=2 is a dependency. Install the extra for the framework and chain you use, such as `x402[fastapi,evm]` or `x402[flask,evm]`.
41
+
42
+ ```python
43
+ import os
44
+
45
+ from cryptonly_x402 import CryptonlyFacilitatorClient
46
+ from x402.mechanisms.evm.exact import ExactEvmServerScheme
47
+ from x402.server import x402ResourceServer
48
+
49
+ facilitator = CryptonlyFacilitatorClient(os.environ["CRYPTONLY_API_KEY"])
50
+
51
+ server = x402ResourceServer(facilitator)
52
+ server.register("eip155:8453", ExactEvmServerScheme())
53
+ ```
54
+
55
+ `api_key` is your Cryptonly API key. It is sent as `x-tenant-api-key` on verify, settle, and supported.
56
+
57
+ ```python
58
+ facilitator = CryptonlyFacilitatorClient(os.environ["CRYPTONLY_API_KEY"])
59
+ ```
60
+
61
+ Flask uses the sync client:
62
+
63
+ ```python
64
+ from cryptonly_x402 import CryptonlyFacilitatorClientSync
65
+ from x402.mechanisms.evm.exact import ExactEvmServerScheme
66
+ from x402.server import x402ResourceServerSync
67
+
68
+ facilitator = CryptonlyFacilitatorClientSync(os.environ["CRYPTONLY_API_KEY"])
69
+
70
+ server = x402ResourceServerSync(facilitator)
71
+ server.register("eip155:8453", ExactEvmServerScheme())
72
+ ```
73
+
74
+ Set `sandbox=True` to use the sandbox facilitator with testnest.
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/cryptonly_x402/__init__.py
4
+ src/cryptonly_x402/client.py
5
+ src/cryptonly_x402/constants.py
6
+ src/cryptonly_x402/py.typed
7
+ src/cryptonly_x402.egg-info/PKG-INFO
8
+ src/cryptonly_x402.egg-info/SOURCES.txt
9
+ src/cryptonly_x402.egg-info/dependency_links.txt
10
+ src/cryptonly_x402.egg-info/requires.txt
11
+ src/cryptonly_x402.egg-info/top_level.txt
12
+ tests/test_client.py
@@ -0,0 +1,4 @@
1
+ x402>=2
2
+
3
+ [dev]
4
+ pytest>=8
@@ -0,0 +1 @@
1
+ cryptonly_x402
@@ -0,0 +1,33 @@
1
+ import pytest
2
+
3
+ from cryptonly_x402 import (
4
+ MERCHANT_API_BASE_URL,
5
+ MERCHANT_API_KEY_HEADER,
6
+ SANDBOX_MERCHANT_API_BASE_URL,
7
+ CryptonlyFacilitatorClient,
8
+ CryptonlyFacilitatorClientSync,
9
+ )
10
+
11
+
12
+ @pytest.mark.parametrize(
13
+ "client_cls",
14
+ [CryptonlyFacilitatorClient, CryptonlyFacilitatorClientSync],
15
+ )
16
+ def test_requires_an_api_key(client_cls):
17
+ with pytest.raises(TypeError, match="api_key is required"):
18
+ client_cls("")
19
+
20
+
21
+ @pytest.mark.parametrize(
22
+ "client_cls",
23
+ [CryptonlyFacilitatorClient, CryptonlyFacilitatorClientSync],
24
+ )
25
+ def test_points_at_production_by_default_and_sandbox_when_asked(client_cls):
26
+ production = client_cls("k")
27
+ assert production.url == f"{MERCHANT_API_BASE_URL}/x402"
28
+
29
+ sandbox = client_cls("k", sandbox=True)
30
+ assert sandbox.url == f"{SANDBOX_MERCHANT_API_BASE_URL}/x402"
31
+ assert sandbox._get_settle_headers()[MERCHANT_API_KEY_HEADER] == "k"
32
+ assert sandbox._get_verify_headers()[MERCHANT_API_KEY_HEADER] == "k"
33
+ assert sandbox._get_supported_headers()[MERCHANT_API_KEY_HEADER] == "k"