diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 724a189..9f5b962 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -27,7 +27,7 @@ repos:
additional_dependencies: ["openai>=3.7.0", "httpx2>=2.12.0", "x402>=2.21.0"]
args: [--strict, --config-file=pyproject.toml]
pass_filenames: false
- entry: mypy src/qntx/openai
+ entry: mypy src/x402_openai
ci:
autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks
diff --git a/Justfile b/Justfile
index 2886d37..5536864 100644
--- a/Justfile
+++ b/Justfile
@@ -21,7 +21,7 @@ format:
# Run the mypy type checker.
typecheck:
- uv run mypy src/qntx/openai
+ uv run mypy src/x402_openai
# Run pytest.
test:
diff --git a/Makefile b/Makefile
index 0efface..e58a7a8 100644
--- a/Makefile
+++ b/Makefile
@@ -18,7 +18,7 @@ format: ## Run ruff formatter (auto-fix)
uv run ruff format .
typecheck: ## Run mypy type checker
- uv run mypy src/qntx/openai
+ uv run mypy src/x402_openai
test: ## Run pytest
uv run pytest
diff --git a/README.md b/README.md
index c59ff08..ea05437 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,11 @@
-# qntx-openai
+# x402-openai
**Drop-in OpenAI Python client with transparent [x402](https://www.x402.org/) payment support.**
-[](https://pypi.org/project/qntx-openai/)
+[](https://pypi.org/project/x402-openai/)
[](https://python.org)
[](https://github.com/qntx/openai-python/actions)
[](LICENSE)
@@ -23,18 +23,16 @@ Supplying `evm` registers both **`exact` and `upto`**. `svm` and `tvm` register
## Installation
```bash
-pip install 'qntx-openai[evm]' # EVM (Ethereum / Base / …)
-pip install 'qntx-openai[svm]' # Solana
-pip install 'qntx-openai[tvm]' # TVM (TON)
-pip install 'qntx-openai[all]' # all chains
+pip install 'x402-openai[evm]' # EVM (Ethereum / Base / …)
+pip install 'x402-openai[svm]' # Solana
+pip install 'x402-openai[tvm]' # TVM (TON)
+pip install 'x402-openai[all]' # all chains
```
-The PyPI name `x402-openai` is abandoned. Install `qntx-openai`.
-
## Quick Start
```python
-from qntx.openai import X402OpenAI
+from x402_openai import X402OpenAI
client = X402OpenAI(evm="0x…")
@@ -52,7 +50,7 @@ Pass `svm="base58…"` instead of `evm` to pay on Solana — the rest of the API
### Streaming
```python
-from qntx.openai import AsyncX402OpenAI
+from x402_openai import AsyncX402OpenAI
client = AsyncX402OpenAI(evm="0x…")
@@ -124,7 +122,7 @@ client = X402OpenAI(
- **SVM `exact`:** the 402 must include `extra.feePayer`. There is no SVM `upto` scheme in Python `x402`.
```python
-from qntx.openai import X402OpenAI, prefer_scheme
+from x402_openai import X402OpenAI, prefer_scheme
client = X402OpenAI(
evm="0x…",
@@ -139,7 +137,7 @@ client = X402OpenAI(
Use policies to prefer a chain or scheme when multiple options remain after spend controls. Policies do not cap spend.
```python
-from qntx.openai import X402OpenAI, prefer_network, prefer_scheme
+from x402_openai import X402OpenAI, prefer_network, prefer_scheme
client = X402OpenAI(
evm="0x…",
@@ -194,9 +192,9 @@ All standard OpenAI options (`base_url`, `timeout`, `max_retries`, …) are forw
| Option | Chain | Install extra |
| :----- | :---- | :------------ |
-| `evm` | EVM | `qntx-openai[evm]` |
-| `svm` | Solana | `qntx-openai[svm]` |
-| `tvm` | TVM | `qntx-openai[tvm]` |
+| `evm` | EVM | `x402-openai[evm]` |
+| `svm` | Solana | `x402-openai[svm]` |
+| `tvm` | TVM | `x402-openai[tvm]` |
## Examples
diff --git a/examples/chat_evm.py b/examples/chat_evm.py
index 92fe01a..cdd155b 100644
--- a/examples/chat_evm.py
+++ b/examples/chat_evm.py
@@ -5,7 +5,7 @@
import os
-from qntx.openai import X402OpenAI
+from x402_openai import X402OpenAI
client = X402OpenAI(evm=os.environ["EVM_PRIVATE_KEY"])
diff --git a/examples/chat_evm_policy.py b/examples/chat_evm_policy.py
index a54855d..b4c457e 100644
--- a/examples/chat_evm_policy.py
+++ b/examples/chat_evm_policy.py
@@ -7,7 +7,7 @@
import os
-from qntx.openai import X402OpenAI, prefer_network, prefer_scheme
+from x402_openai import X402OpenAI, prefer_network, prefer_scheme
client = X402OpenAI(
evm=os.environ["EVM_PRIVATE_KEY"],
diff --git a/examples/chat_multichain_policy.py b/examples/chat_multichain_policy.py
index c37f894..8e21708 100644
--- a/examples/chat_multichain_policy.py
+++ b/examples/chat_multichain_policy.py
@@ -11,7 +11,7 @@
import os
-from qntx.openai import X402OpenAI, prefer_network, prefer_scheme
+from x402_openai import X402OpenAI, prefer_network, prefer_scheme
client = X402OpenAI(
evm=os.environ["EVM_PRIVATE_KEY"],
diff --git a/examples/chat_policy.py b/examples/chat_policy.py
index 45e7c60..4aab4a3 100644
--- a/examples/chat_policy.py
+++ b/examples/chat_policy.py
@@ -7,7 +7,7 @@
import os
-from qntx.openai import X402OpenAI, prefer_network, prefer_scheme
+from x402_openai import X402OpenAI, prefer_network, prefer_scheme
client = X402OpenAI(
evm=os.environ["EVM_PRIVATE_KEY"],
diff --git a/examples/chat_svm.py b/examples/chat_svm.py
index 5ac2af9..e539c68 100644
--- a/examples/chat_svm.py
+++ b/examples/chat_svm.py
@@ -5,7 +5,7 @@
import os
-from qntx.openai import X402OpenAI
+from x402_openai import X402OpenAI
client = X402OpenAI(svm=os.environ["SOLANA_PRIVATE_KEY"])
diff --git a/examples/chat_tvm.py b/examples/chat_tvm.py
index d24f585..e7581b9 100644
--- a/examples/chat_tvm.py
+++ b/examples/chat_tvm.py
@@ -8,7 +8,7 @@
import os
-from qntx.openai import X402OpenAI
+from x402_openai import X402OpenAI
client = X402OpenAI(tvm=os.environ["TVM_PRIVATE_KEY"])
try:
diff --git a/examples/chat_upto.py b/examples/chat_upto.py
index 463433e..318219b 100644
--- a/examples/chat_upto.py
+++ b/examples/chat_upto.py
@@ -8,7 +8,7 @@
import os
-from qntx.openai import X402OpenAI, prefer_scheme
+from x402_openai import X402OpenAI, prefer_scheme
client = X402OpenAI(
evm=os.environ["EVM_PRIVATE_KEY"],
diff --git a/examples/models.py b/examples/models.py
index cdb7a26..cf292ec 100644
--- a/examples/models.py
+++ b/examples/models.py
@@ -5,7 +5,7 @@
import os
-from qntx.openai import X402OpenAI
+from x402_openai import X402OpenAI
client = X402OpenAI(evm=os.environ["EVM_PRIVATE_KEY"])
diff --git a/examples/streaming_evm.py b/examples/streaming_evm.py
index 77a95e8..f77154d 100644
--- a/examples/streaming_evm.py
+++ b/examples/streaming_evm.py
@@ -6,7 +6,7 @@
import asyncio
import os
-from qntx.openai import AsyncX402OpenAI
+from x402_openai import AsyncX402OpenAI
async def main() -> None:
diff --git a/examples/streaming_evm_policy.py b/examples/streaming_evm_policy.py
index c85219f..e0a185b 100644
--- a/examples/streaming_evm_policy.py
+++ b/examples/streaming_evm_policy.py
@@ -8,7 +8,7 @@
import asyncio
import os
-from qntx.openai import AsyncX402OpenAI, prefer_network, prefer_scheme
+from x402_openai import AsyncX402OpenAI, prefer_network, prefer_scheme
async def main() -> None:
diff --git a/examples/streaming_svm.py b/examples/streaming_svm.py
index 78108c5..5b49629 100644
--- a/examples/streaming_svm.py
+++ b/examples/streaming_svm.py
@@ -6,7 +6,7 @@
import asyncio
import os
-from qntx.openai import AsyncX402OpenAI
+from x402_openai import AsyncX402OpenAI
async def main() -> None:
diff --git a/pyproject.toml b/pyproject.toml
index d03af64..f4b7ce4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,7 +3,7 @@ requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
-name = "qntx-openai"
+name = "x402-openai"
version = "1.0.0"
description = "Drop-in OpenAI Python client with transparent x402 payment support."
readme = "README.md"
@@ -43,9 +43,9 @@ tvm = [
"x402[tvm]>=2.21.0",
]
all = [
- "qntx-openai[evm]",
- "qntx-openai[svm]",
- "qntx-openai[tvm]",
+ "x402-openai[evm]",
+ "x402-openai[svm]",
+ "x402-openai[tvm]",
]
dev = [
"pytest>=8.0",
@@ -62,7 +62,7 @@ Repository = "https://github.com/qntx/openai-python"
Issues = "https://github.com/qntx/openai-python/issues"
[tool.hatch.build.targets.wheel]
-packages = ["src/qntx"]
+packages = ["src/x402_openai"]
[tool.ruff]
target-version = "py312"
@@ -87,15 +87,13 @@ ignore = [
]
[tool.ruff.lint.isort]
-known-first-party = ["qntx"]
+known-first-party = ["x402_openai"]
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_configs = true
-namespace_packages = true
-explicit_package_bases = true
mypy_path = "src"
[[tool.mypy.overrides]]
diff --git a/src/qntx/openai/__init__.py b/src/x402_openai/__init__.py
similarity index 72%
rename from src/qntx/openai/__init__.py
rename to src/x402_openai/__init__.py
index ec88936..5ba09de 100644
--- a/src/qntx/openai/__init__.py
+++ b/src/x402_openai/__init__.py
@@ -1,8 +1,8 @@
-"""qntx-openai — Drop-in OpenAI client with transparent x402 payment.
+"""x402-openai — Drop-in OpenAI client with transparent x402 payment.
Quick start::
- from qntx.openai import prefer_scheme, X402OpenAI
+ from x402_openai import prefer_scheme, X402OpenAI
client = X402OpenAI(evm="0x…")
@@ -24,9 +24,9 @@
from x402 import SpendControls, x402Client, x402ClientSync
-from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
-from qntx.openai._client import AsyncX402OpenAI, X402OpenAI
-from qntx.openai._policies import prefer_network, prefer_scheme
+from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+from x402_openai._client import AsyncX402OpenAI, X402OpenAI
+from x402_openai._policies import prefer_network, prefer_scheme
__all__ = [
"AsyncX402OpenAI",
diff --git a/src/qntx/openai/_chains/__init__.py b/src/x402_openai/_chains/__init__.py
similarity index 58%
rename from src/qntx/openai/_chains/__init__.py
rename to src/x402_openai/_chains/__init__.py
index 5f01e95..0939e20 100644
--- a/src/qntx/openai/_chains/__init__.py
+++ b/src/x402_openai/_chains/__init__.py
@@ -2,7 +2,7 @@
from __future__ import annotations
-from qntx.openai._chains._register import ChainHandles, register_chains
-from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+from x402_openai._chains._register import ChainHandles, register_chains
+from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
__all__ = ["ChainHandles", "EvmConfig", "SvmConfig", "TvmConfig", "register_chains"]
diff --git a/src/qntx/openai/_chains/_evm.py b/src/x402_openai/_chains/_evm.py
similarity index 92%
rename from src/qntx/openai/_chains/_evm.py
rename to src/x402_openai/_chains/_evm.py
index 0e59376..131a946 100644
--- a/src/qntx/openai/_chains/_evm.py
+++ b/src/x402_openai/_chains/_evm.py
@@ -7,7 +7,7 @@
if TYPE_CHECKING:
from x402 import x402Client, x402ClientSync
- from qntx.openai._chains._types import EvmConfig
+ from x402_openai._chains._types import EvmConfig
def register_evm(client: x402Client | x402ClientSync, config: EvmConfig) -> None:
@@ -17,7 +17,7 @@ def register_evm(client: x402Client | x402ClientSync, config: EvmConfig) -> None
from x402.mechanisms.evm.upto import UptoEvmScheme
except ImportError as e:
raise ImportError(
- "EVM key provided but x402[evm] is not installed. pip install 'qntx-openai[evm]'"
+ "EVM key provided but x402[evm] is not installed. pip install 'x402-openai[evm]'"
) from e
account = Account.from_key(config.private_key)
diff --git a/src/qntx/openai/_chains/_register.py b/src/x402_openai/_chains/_register.py
similarity index 84%
rename from src/qntx/openai/_chains/_register.py
rename to src/x402_openai/_chains/_register.py
index a360958..2f06c2a 100644
--- a/src/qntx/openai/_chains/_register.py
+++ b/src/x402_openai/_chains/_register.py
@@ -4,16 +4,16 @@
from typing import TYPE_CHECKING
-from qntx.openai._chains._evm import register_evm
-from qntx.openai._chains._svm import register_svm
-from qntx.openai._chains._tvm import register_tvm
-from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+from x402_openai._chains._evm import register_evm
+from x402_openai._chains._svm import register_svm
+from x402_openai._chains._tvm import register_tvm
+from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
if TYPE_CHECKING:
from x402 import x402Client, x402ClientSync
- from qntx.openai._chains._tvm import _TvmScheme
- from qntx.openai._payments import PaymentSourceOptions
+ from x402_openai._chains._tvm import _TvmScheme
+ from x402_openai._payments import PaymentSourceOptions
class ChainHandles:
diff --git a/src/qntx/openai/_chains/_svm.py b/src/x402_openai/_chains/_svm.py
similarity index 89%
rename from src/qntx/openai/_chains/_svm.py
rename to src/x402_openai/_chains/_svm.py
index c0b4756..013bdcc 100644
--- a/src/qntx/openai/_chains/_svm.py
+++ b/src/x402_openai/_chains/_svm.py
@@ -7,7 +7,7 @@
if TYPE_CHECKING:
from x402 import x402Client, x402ClientSync
- from qntx.openai._chains._types import SvmConfig
+ from x402_openai._chains._types import SvmConfig
def register_svm(client: x402Client | x402ClientSync, config: SvmConfig) -> None:
@@ -16,7 +16,7 @@ def register_svm(client: x402Client | x402ClientSync, config: SvmConfig) -> None
from x402.mechanisms.svm.exact import ExactSvmScheme
except ImportError as e:
raise ImportError(
- "SVM key provided but x402[svm] is not installed. pip install 'qntx-openai[svm]'"
+ "SVM key provided but x402[svm] is not installed. pip install 'x402-openai[svm]'"
) from e
signer = KeypairSigner.from_base58(config.private_key)
diff --git a/src/qntx/openai/_chains/_tvm.py b/src/x402_openai/_chains/_tvm.py
similarity index 93%
rename from src/qntx/openai/_chains/_tvm.py
rename to src/x402_openai/_chains/_tvm.py
index 01d9e91..7de0bb9 100644
--- a/src/qntx/openai/_chains/_tvm.py
+++ b/src/x402_openai/_chains/_tvm.py
@@ -7,7 +7,7 @@
if TYPE_CHECKING:
from x402 import x402Client, x402ClientSync
- from qntx.openai._chains._types import TvmConfig
+ from x402_openai._chains._types import TvmConfig
class _TvmScheme(Protocol):
@@ -24,7 +24,7 @@ def register_tvm(client: x402Client | x402ClientSync, config: TvmConfig) -> _Tvm
from x402.mechanisms.tvm.exact import ExactTvmScheme
except ImportError as e:
raise ImportError(
- "TVM key provided but x402[tvm] is not installed. pip install 'qntx-openai[tvm]'"
+ "TVM key provided but x402[tvm] is not installed. pip install 'x402-openai[tvm]'"
) from e
network = config.network or TVM_MAINNET
diff --git a/src/qntx/openai/_chains/_types.py b/src/x402_openai/_chains/_types.py
similarity index 100%
rename from src/qntx/openai/_chains/_types.py
rename to src/x402_openai/_chains/_types.py
diff --git a/src/qntx/openai/_client.py b/src/x402_openai/_client.py
similarity index 98%
rename from src/qntx/openai/_client.py
rename to src/x402_openai/_client.py
index 9755605..e37189a 100644
--- a/src/qntx/openai/_client.py
+++ b/src/x402_openai/_client.py
@@ -7,22 +7,22 @@
from typing import TYPE_CHECKING, Any, Literal, Self
import httpx2
-from httpx2._utils import get_environment_proxies
-
import openai
+from httpx2._utils import get_environment_proxies
from openai import DefaultAsyncHttpx2Client, DefaultHttpx2Client
-from qntx.openai._payments import (
+
+from x402_openai._payments import (
BuiltClient,
PaymentSourceOptions,
assert_payment_options,
build_x402_client,
)
-from qntx.openai._transport import X402Httpx2AsyncTransport, X402Httpx2SyncTransport
+from x402_openai._transport import X402Httpx2AsyncTransport, X402Httpx2SyncTransport
if TYPE_CHECKING:
from x402 import SpendControls, x402Client, x402ClientSync
- from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+ from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
DEFAULT_BASE_URL = "https://llm.qntx.org/v1"
_REMOVED = ("wallet", "wallets", "mnemonic", "max_amount", "http_client")
diff --git a/src/qntx/openai/_payments.py b/src/x402_openai/_payments.py
similarity index 96%
rename from src/qntx/openai/_payments.py
rename to src/x402_openai/_payments.py
index 9f77575..ff17131 100644
--- a/src/qntx/openai/_payments.py
+++ b/src/x402_openai/_payments.py
@@ -9,10 +9,10 @@
from x402 import SpendControls, x402Client, x402ClientSync
from x402.http import x402HTTPClient, x402HTTPClientSync
-from qntx.openai._chains._register import register_chains
+from x402_openai._chains._register import register_chains
if TYPE_CHECKING:
- from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+ from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
Policy = Callable[[int, list[Any]], list[Any]]
Selector = Callable[[int, list[Any]], Any]
diff --git a/src/qntx/openai/_policies.py b/src/x402_openai/_policies.py
similarity index 95%
rename from src/qntx/openai/_policies.py
rename to src/x402_openai/_policies.py
index 260f151..9b1235d 100644
--- a/src/qntx/openai/_policies.py
+++ b/src/x402_openai/_policies.py
@@ -5,7 +5,7 @@
from typing import TYPE_CHECKING, Any
if TYPE_CHECKING:
- from qntx.openai._payments import Policy
+ from x402_openai._payments import Policy
def prefer_network(network: str) -> Policy:
diff --git a/src/qntx/openai/_transport.py b/src/x402_openai/_transport.py
similarity index 99%
rename from src/qntx/openai/_transport.py
rename to src/x402_openai/_transport.py
index 1707b31..83d6599 100644
--- a/src/qntx/openai/_transport.py
+++ b/src/x402_openai/_transport.py
@@ -17,7 +17,7 @@
from x402.http import x402HTTPClient, x402HTTPClientSync
-logger = logging.getLogger("qntx.openai")
+logger = logging.getLogger("x402_openai")
RETRY_KEY = "_x402_is_retry"
RECOVERY_KEY = "_x402_is_recovery"
diff --git a/src/qntx/openai/py.typed b/src/x402_openai/py.typed
similarity index 100%
rename from src/qntx/openai/py.typed
rename to src/x402_openai/py.typed
diff --git a/tests/test_chains_evm.py b/tests/test_chains_evm.py
index ce6e6af..6374d33 100644
--- a/tests/test_chains_evm.py
+++ b/tests/test_chains_evm.py
@@ -10,10 +10,10 @@
from x402.mechanisms.evm.signers import EthAccountSignerWithRPC
from x402.mechanisms.evm.upto import UptoEvmScheme
-from qntx.openai._chains._evm import register_evm
-from qntx.openai._chains._register import register_chains
-from qntx.openai._chains._types import EvmConfig
-from qntx.openai._payments import PaymentSourceOptions, build_x402_client
+from x402_openai._chains._evm import register_evm
+from x402_openai._chains._register import register_chains
+from x402_openai._chains._types import EvmConfig
+from x402_openai._payments import PaymentSourceOptions, build_x402_client
EVM_KEY = "0xac0974dac38f24671676c33098b7abf185c4d7b8d04844c06a56a24126c6dcbd"
diff --git a/tests/test_chains_svm.py b/tests/test_chains_svm.py
index 162a982..44842fc 100644
--- a/tests/test_chains_svm.py
+++ b/tests/test_chains_svm.py
@@ -9,11 +9,11 @@
from x402.mechanisms.svm.exact import ExactSvmScheme
from x402.schemas import PaymentRequired, PaymentRequirements, ResourceInfo
-from qntx.openai import prefer_scheme
-from qntx.openai._chains._register import register_chains
-from qntx.openai._chains._svm import register_svm
-from qntx.openai._chains._types import SvmConfig
-from qntx.openai._payments import PaymentSourceOptions, build_x402_client
+from x402_openai import prefer_scheme
+from x402_openai._chains._register import register_chains
+from x402_openai._chains._svm import register_svm
+from x402_openai._chains._types import SvmConfig
+from x402_openai._payments import PaymentSourceOptions, build_x402_client
# 64-byte Ed25519 secret (seed + pubkey), base58. Seed is 31 zero bytes + 0x01.
SVM_KEY = "1111111111111111111111111111111PPm2a2NNZH2EFJ5UkEjkH9Fcxn8cvjTmZDKQQisyLDmA"
diff --git a/tests/test_chains_tvm.py b/tests/test_chains_tvm.py
index 766bdb6..fe60f11 100644
--- a/tests/test_chains_tvm.py
+++ b/tests/test_chains_tvm.py
@@ -6,10 +6,10 @@
import pytest
-from qntx.openai._chains._register import register_chains
-from qntx.openai._chains._tvm import register_tvm
-from qntx.openai._chains._types import TvmConfig
-from qntx.openai._payments import PaymentSourceOptions, build_x402_client
+from x402_openai._chains._register import register_chains
+from x402_openai._chains._tvm import register_tvm
+from x402_openai._chains._types import TvmConfig
+from x402_openai._payments import PaymentSourceOptions, build_x402_client
TVM_KEY = "11" * 32
@@ -194,7 +194,7 @@ def test_invalid_key_is_not_missing_extra() -> None:
with pytest.raises(ValueError) as exc:
register_tvm(client, TvmConfig(private_key="00")) # type: ignore[arg-type]
assert "not installed" not in str(exc.value)
- assert "qntx-openai[tvm]" not in str(exc.value)
+ assert "x402-openai[tvm]" not in str(exc.value)
def test_dispose_mocks_real_scheme_close(monkeypatch: pytest.MonkeyPatch) -> None:
diff --git a/tests/test_client.py b/tests/test_client.py
index f2426da..0d7a0ec 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -11,9 +11,9 @@
import pytest
from x402 import x402Client, x402ClientSync
-import qntx.openai as api
-from qntx.openai import AsyncX402OpenAI, SvmConfig, TvmConfig, X402OpenAI
-from qntx.openai._payments import BuiltClient
+import x402_openai as api
+from x402_openai import AsyncX402OpenAI, SvmConfig, TvmConfig, X402OpenAI
+from x402_openai._payments import BuiltClient
EVM_KEY = "0xac0974dac38f24671676c33098b7abf185c4d7b8d04844c06a56a24126c6dcbd"
TVM_KEY = "11" * 32
@@ -45,7 +45,7 @@ def test_throws_on_empty_evm_string() -> None:
def test_throws_on_empty_evm_config() -> None:
- from qntx.openai import EvmConfig
+ from x402_openai import EvmConfig
with pytest.raises(ValueError, match="non-empty"):
X402OpenAI(evm=EvmConfig(private_key=""))
@@ -57,7 +57,7 @@ def test_throws_on_empty_svm_string() -> None:
def test_throws_on_empty_svm_config() -> None:
- from qntx.openai import SvmConfig
+ from x402_openai import SvmConfig
with pytest.raises(ValueError, match="'svm' private key must be a non-empty string"):
X402OpenAI(svm=SvmConfig(private_key=""))
@@ -209,7 +209,7 @@ def run_ensure() -> None:
except BaseException as e:
errors.append(e)
- with patch("qntx.openai._client.build_x402_client", fake_build):
+ with patch("x402_openai._client.build_x402_client", fake_build):
thread = threading.Thread(target=run_ensure)
thread.start()
assert built_started.wait(timeout=2)
@@ -231,7 +231,7 @@ def fake_build(options: object, *, sync: bool) -> BuiltClient:
return BuiltClient(http=object(), dispose=lambda: None)
client = AsyncX402OpenAI(evm=EVM_KEY)
- with patch("qntx.openai._client.build_x402_client", fake_build):
+ with patch("x402_openai._client.build_x402_client", fake_build):
h1, h2 = await asyncio.gather(
client._lifecycle._ensure_http(),
client._lifecycle._ensure_http(),
@@ -340,7 +340,7 @@ def fake_build(options: object, *, sync: bool) -> BuiltClient:
await lifecycle._lock.acquire()
try:
- with patch("qntx.openai._client.build_x402_client", fake_build):
+ with patch("x402_openai._client.build_x402_client", fake_build):
ensure_task = asyncio.create_task(lifecycle._ensure_http())
await asyncio.sleep(0)
close_task = asyncio.create_task(client.close())
@@ -371,7 +371,7 @@ def fake_build(options: object, *, sync: bool) -> BuiltClient:
return BuiltClient(http=object(), dispose=dispose)
with (
- patch("qntx.openai._client.build_x402_client", fake_build),
+ patch("x402_openai._client.build_x402_client", fake_build),
pytest.raises(RuntimeError, match="X402OpenAI is closed"),
):
await lifecycle._ensure_http()
@@ -387,9 +387,9 @@ def capturing_transport(*args: Any, **kwargs: Any) -> httpx2.HTTPTransport:
captured.append(kwargs)
return real(*args, **kwargs)
- monkeypatch.setattr("qntx.openai._client.httpx2.HTTPTransport", capturing_transport)
+ monkeypatch.setattr("x402_openai._client.httpx2.HTTPTransport", capturing_transport)
monkeypatch.setattr(
- "qntx.openai._client.get_environment_proxies",
+ "x402_openai._client.get_environment_proxies",
lambda: {"https://": "http://proxy.example:8080"},
)
X402OpenAI(evm="0x1")
diff --git a/tests/test_missing_extra.py b/tests/test_missing_extra.py
index e49cd9c..02577f3 100644
--- a/tests/test_missing_extra.py
+++ b/tests/test_missing_extra.py
@@ -4,7 +4,7 @@
import pytest
-from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
def test_missing_evm_extra_import_error(monkeypatch: pytest.MonkeyPatch) -> None:
@@ -14,13 +14,13 @@ def test_missing_evm_extra_import_error(monkeypatch: pytest.MonkeyPatch) -> None
if name.startswith("eth_account.") or name.startswith("x402.mechanisms.evm."):
monkeypatch.setitem(sys.modules, name, None)
- from qntx.openai._chains._evm import register_evm
+ from x402_openai._chains._evm import register_evm
class _Client:
def register(self, network: str, scheme: object) -> None:
return None
- with pytest.raises(ImportError, match=r"qntx-openai\[evm\]"):
+ with pytest.raises(ImportError, match=r"x402-openai\[evm\]"):
register_evm(_Client(), EvmConfig(private_key="0x1")) # type: ignore[arg-type]
@@ -33,13 +33,13 @@ def test_missing_svm_extra_import_error(monkeypatch: pytest.MonkeyPatch) -> None
if name == "x402.mechanisms.svm" or name.startswith("x402.mechanisms.svm."):
monkeypatch.setitem(sys.modules, name, None)
- from qntx.openai._chains._svm import register_svm
+ from x402_openai._chains._svm import register_svm
class _Client:
def register(self, network: str, scheme: object) -> None:
return None
- with pytest.raises(ImportError, match=r"qntx-openai\[svm\]"):
+ with pytest.raises(ImportError, match=r"x402-openai\[svm\]"):
register_svm(_Client(), SvmConfig(private_key="base58")) # type: ignore[arg-type]
@@ -55,11 +55,11 @@ def test_missing_tvm_extra_import_error(monkeypatch: pytest.MonkeyPatch) -> None
):
monkeypatch.setitem(sys.modules, name, None)
- from qntx.openai._chains._tvm import register_tvm
+ from x402_openai._chains._tvm import register_tvm
class _Client:
def register(self, network: str, scheme: object) -> None:
return None
- with pytest.raises(ImportError, match=r"qntx-openai\[tvm\]"):
+ with pytest.raises(ImportError, match=r"x402-openai\[tvm\]"):
register_tvm(_Client(), TvmConfig(private_key="11" * 32)) # type: ignore[arg-type]
diff --git a/tests/test_payments.py b/tests/test_payments.py
index a7d7803..2b81125 100644
--- a/tests/test_payments.py
+++ b/tests/test_payments.py
@@ -8,9 +8,9 @@
from x402.http import x402HTTPClient, x402HTTPClientSync
from x402.schemas import PaymentRequired, PaymentRequirements, ResourceInfo
-from qntx.openai._chains._register import ChainHandles
-from qntx.openai._chains._types import EvmConfig, SvmConfig, TvmConfig
-from qntx.openai._payments import (
+from x402_openai._chains._register import ChainHandles
+from x402_openai._chains._types import EvmConfig, SvmConfig, TvmConfig
+from x402_openai._payments import (
PREBUILT_EXCLUSIVE,
PaymentSourceOptions,
assert_payment_options,
@@ -176,8 +176,8 @@ def set_spend_controls(self, controls: object) -> Any:
return super().set_spend_controls(controls) # type: ignore[misc]
with (
- patch("qntx.openai._payments.x402ClientSync", _Client),
- patch("qntx.openai._payments.register_chains", _noop_register),
+ patch("x402_openai._payments.x402ClientSync", _Client),
+ patch("x402_openai._payments.register_chains", _noop_register),
):
build_x402_client(PaymentSourceOptions(evm=EVM_KEY), sync=True)
assert calls == []
@@ -192,8 +192,8 @@ def set_spend_controls(self, controls: object) -> Any:
return super().set_spend_controls(controls) # type: ignore[misc]
with (
- patch("qntx.openai._payments.x402ClientSync", _Client),
- patch("qntx.openai._payments.register_chains", _noop_register),
+ patch("x402_openai._payments.x402ClientSync", _Client),
+ patch("x402_openai._payments.register_chains", _noop_register),
):
build_x402_client(PaymentSourceOptions(evm=EVM_KEY, spend_controls=False), sync=True)
assert calls == [False]
@@ -205,7 +205,7 @@ def _core(built: object) -> x402ClientSync:
def test_spend_controls_omitted_rejects_2_usdc() -> None:
- with patch("qntx.openai._payments.register_chains", _noop_register):
+ with patch("x402_openai._payments.register_chains", _noop_register):
built = build_x402_client(PaymentSourceOptions(evm=EVM_KEY), sync=True)
core = _core(built)
core.register("eip155:8453", StubUsdcScheme("exact"))
@@ -214,7 +214,7 @@ def test_spend_controls_omitted_rejects_2_usdc() -> None:
def test_spend_controls_explicit_1_rejects_2_usdc() -> None:
- with patch("qntx.openai._payments.register_chains", _noop_register):
+ with patch("x402_openai._payments.register_chains", _noop_register):
built = build_x402_client(
PaymentSourceOptions(evm=EVM_KEY, spend_controls={"max_amount_per_payment": "$1"}),
sync=True,
@@ -226,7 +226,7 @@ def test_spend_controls_explicit_1_rejects_2_usdc() -> None:
def test_spend_controls_5_allows_2_usdc() -> None:
- with patch("qntx.openai._payments.register_chains", _noop_register):
+ with patch("x402_openai._payments.register_chains", _noop_register):
built = build_x402_client(
PaymentSourceOptions(evm=EVM_KEY, spend_controls={"max_amount_per_payment": "$5"}),
sync=True,
@@ -238,7 +238,7 @@ def test_spend_controls_5_allows_2_usdc() -> None:
def test_spend_controls_false_allows_2_usdc() -> None:
- with patch("qntx.openai._payments.register_chains", _noop_register):
+ with patch("x402_openai._payments.register_chains", _noop_register):
built = build_x402_client(
PaymentSourceOptions(evm=EVM_KEY, spend_controls=False), sync=True
)
@@ -249,10 +249,10 @@ def test_spend_controls_false_allows_2_usdc() -> None:
def test_build_registers_policies() -> None:
- from qntx.openai import prefer_scheme
+ from x402_openai import prefer_scheme
policy = prefer_scheme("upto")
- with patch("qntx.openai._payments.register_chains", _noop_register):
+ with patch("x402_openai._payments.register_chains", _noop_register):
built = build_x402_client(
PaymentSourceOptions(evm=EVM_KEY, policies=[policy]),
sync=True,
@@ -262,7 +262,7 @@ def test_build_registers_policies() -> None:
def test_selector_runs_after_spend_controls() -> None:
- with patch("qntx.openai._payments.register_chains", _noop_register):
+ with patch("x402_openai._payments.register_chains", _noop_register):
built = build_x402_client(
PaymentSourceOptions(
evm=EVM_KEY,
diff --git a/tests/test_policies.py b/tests/test_policies.py
index ddb5657..d1b919e 100644
--- a/tests/test_policies.py
+++ b/tests/test_policies.py
@@ -2,7 +2,7 @@
from typing import Any, NamedTuple
-from qntx.openai import prefer_network, prefer_scheme
+from x402_openai import prefer_network, prefer_scheme
class _Req(NamedTuple):
diff --git a/tests/test_transport.py b/tests/test_transport.py
index e410eb4..2ed2e87 100644
--- a/tests/test_transport.py
+++ b/tests/test_transport.py
@@ -9,7 +9,7 @@
import httpx2
import pytest
-from qntx.openai._transport import (
+from x402_openai._transport import (
RECOVERY_KEY,
RETRY_KEY,
PaymentError,
diff --git a/uv.lock b/uv.lock
index dcdc71c..719efa8 100644
--- a/uv.lock
+++ b/uv.lock
@@ -1750,64 +1750,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
]
-[[package]]
-name = "qntx-openai"
-version = "1.0.0"
-source = { editable = "." }
-dependencies = [
- { name = "httpx2" },
- { name = "openai" },
- { name = "x402" },
-]
-
-[package.optional-dependencies]
-all = [
- { name = "eth-account" },
- { name = "solana" },
- { name = "x402", extra = ["evm", "svm", "tvm"] },
-]
-dev = [
- { name = "build" },
- { name = "mypy" },
- { name = "pre-commit" },
- { name = "pytest" },
- { name = "pytest-asyncio" },
- { name = "ruff" },
-]
-evm = [
- { name = "eth-account" },
- { name = "x402", extra = ["evm"] },
-]
-svm = [
- { name = "solana" },
- { name = "x402", extra = ["svm"] },
-]
-tvm = [
- { name = "x402", extra = ["tvm"] },
-]
-
-[package.metadata]
-requires-dist = [
- { name = "build", marker = "extra == 'dev'", specifier = ">=1.0" },
- { name = "eth-account", marker = "extra == 'evm'", specifier = ">=0.13.0" },
- { name = "httpx2", specifier = ">=2.12.0" },
- { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.0" },
- { name = "openai", specifier = ">=3.7.0" },
- { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.0" },
- { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" },
- { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24" },
- { name = "qntx-openai", extras = ["evm"], marker = "extra == 'all'" },
- { name = "qntx-openai", extras = ["svm"], marker = "extra == 'all'" },
- { name = "qntx-openai", extras = ["tvm"], marker = "extra == 'all'" },
- { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8" },
- { name = "solana", marker = "extra == 'svm'", specifier = ">=0.36.0,<0.40" },
- { name = "x402", specifier = ">=2.21.0" },
- { name = "x402", extras = ["evm"], marker = "extra == 'evm'", specifier = ">=2.21.0" },
- { name = "x402", extras = ["svm"], marker = "extra == 'svm'", specifier = ">=2.21.0" },
- { name = "x402", extras = ["tvm"], marker = "extra == 'tvm'", specifier = ">=2.21.0" },
-]
-provides-extras = ["evm", "svm", "tvm", "all", "dev"]
-
[[package]]
name = "regex"
version = "2026.1.15"
@@ -2274,6 +2216,64 @@ tvm = [
{ name = "pytoniq-core" },
]
+[[package]]
+name = "x402-openai"
+version = "1.0.0"
+source = { editable = "." }
+dependencies = [
+ { name = "httpx2" },
+ { name = "openai" },
+ { name = "x402" },
+]
+
+[package.optional-dependencies]
+all = [
+ { name = "eth-account" },
+ { name = "solana" },
+ { name = "x402", extra = ["evm", "svm", "tvm"] },
+]
+dev = [
+ { name = "build" },
+ { name = "mypy" },
+ { name = "pre-commit" },
+ { name = "pytest" },
+ { name = "pytest-asyncio" },
+ { name = "ruff" },
+]
+evm = [
+ { name = "eth-account" },
+ { name = "x402", extra = ["evm"] },
+]
+svm = [
+ { name = "solana" },
+ { name = "x402", extra = ["svm"] },
+]
+tvm = [
+ { name = "x402", extra = ["tvm"] },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "build", marker = "extra == 'dev'", specifier = ">=1.0" },
+ { name = "eth-account", marker = "extra == 'evm'", specifier = ">=0.13.0" },
+ { name = "httpx2", specifier = ">=2.12.0" },
+ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.0" },
+ { name = "openai", specifier = ">=3.7.0" },
+ { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.0" },
+ { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0" },
+ { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24" },
+ { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8" },
+ { name = "solana", marker = "extra == 'svm'", specifier = ">=0.36.0,<0.40" },
+ { name = "x402", specifier = ">=2.21.0" },
+ { name = "x402", extras = ["evm"], marker = "extra == 'evm'", specifier = ">=2.21.0" },
+ { name = "x402", extras = ["svm"], marker = "extra == 'svm'", specifier = ">=2.21.0" },
+ { name = "x402", extras = ["tvm"], marker = "extra == 'tvm'", specifier = ">=2.21.0" },
+ { name = "x402-openai", extras = ["evm"], marker = "extra == 'all'" },
+ { name = "x402-openai", extras = ["svm"], marker = "extra == 'all'" },
+ { name = "x402-openai", extras = ["tvm"], marker = "extra == 'all'" },
+]
+provides-extras = ["evm", "svm", "tvm", "all", "dev"]
+
[[package]]
name = "yarl"
version = "1.22.0"