diff --git a/pyproject.toml b/pyproject.toml index 19a5164..b0dcfe7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ dependencies = [ "setuptools>=21.0.0", "Flask>=3.0.0", "gunicorn>=23.0.0", - "og-x402[evm]==0.0.1.dev6", + "og-x402[evm]>=0.0.1.dev9", "fastapi>=0.128.0", "uvicorn[standard]>=0.40.0", "pydantic>=2.12.5", diff --git a/tee_gateway/__main__.py b/tee_gateway/__main__.py index 18f8117..fd36b24 100644 --- a/tee_gateway/__main__.py +++ b/tee_gateway/__main__.py @@ -27,17 +27,20 @@ from x402.http.types import RouteConfig from x402.mechanisms.evm.exact import ExactEvmServerScheme from x402.mechanisms.evm.upto import UptoEvmServerScheme +from x402.extensions.erc20_approval_gas_sponsoring import ( + declare_erc20_approval_gas_sponsoring_extension, +) from x402.schemas import AssetAmount from x402.server import x402ResourceServerSync from x402.session import SessionStore -import types as _types import x402.http.middleware.flask as x402_flask +import types as _types from .util import dynamic_session_cost_calculator from .definitions import ( - BASE_TESTNET_NETWORK, EVM_PAYMENT_ADDRESS, - BASE_OPG_ADDRESS, + BASE_MAINNET_NETWORK, + BASE_MAINNET_OPG_ADDRESS, CHAT_COMPLETIONS_OPG_SESSION_MAX_SPEND, COMPLETIONS_OPG_SESSION_MAX_SPEND, FACILITATOR_URL, @@ -108,8 +111,10 @@ def _shutdown_heartbeat(): server = x402ResourceServerSync(facilitator) store = SessionStore() -server.register(BASE_TESTNET_NETWORK, ExactEvmServerScheme()) -server.register(BASE_TESTNET_NETWORK, UptoEvmServerScheme()) +server.register(BASE_MAINNET_NETWORK, ExactEvmServerScheme()) + +# Upto scheme registrations (permit2-based, variable settlement) +server.register(BASE_MAINNET_NETWORK, UptoEvmServerScheme()) routes = { "POST /v1/chat/completions": RouteConfig( @@ -119,16 +124,19 @@ def _shutdown_heartbeat(): pay_to=EVM_PAYMENT_ADDRESS, price=AssetAmount( amount=CHAT_COMPLETIONS_OPG_SESSION_MAX_SPEND, - asset=BASE_OPG_ADDRESS, + asset=BASE_MAINNET_OPG_ADDRESS, extra={ - "name": "OPG", - "version": "2", + "name": "OpenGradient", + "version": "1", "assetTransferMethod": "permit2", }, ), - network=BASE_TESTNET_NETWORK, + network=BASE_MAINNET_NETWORK, ), ], + extensions={ + **declare_erc20_approval_gas_sponsoring_extension(), + }, mime_type="application/json", description="Chat completion", ), @@ -139,16 +147,19 @@ def _shutdown_heartbeat(): pay_to=EVM_PAYMENT_ADDRESS, price=AssetAmount( amount=COMPLETIONS_OPG_SESSION_MAX_SPEND, - asset=BASE_OPG_ADDRESS, + asset=BASE_MAINNET_OPG_ADDRESS, extra={ - "name": "OPG", - "version": "2", + "name": "OpenGradient", + "version": "1", "assetTransferMethod": "permit2", }, ), - network=BASE_TESTNET_NETWORK, + network=BASE_MAINNET_NETWORK, ), ], + extensions={ + **declare_erc20_approval_gas_sponsoring_extension(), + }, mime_type="application/json", description="Completion", ), @@ -463,7 +474,7 @@ def _strict_resolve_session_request_cost( return self._coerce_non_negative_int(dynamic_cost) -_payment_mw._resolve_session_request_cost = _types.MethodType( # type: ignore[method-assign] +_payment_mw._resolve_session_request_cost = _types.MethodType( # type: ignore[method-assign, attr-defined] _strict_resolve_session_request_cost, _payment_mw ) diff --git a/tee_gateway/definitions.py b/tee_gateway/definitions.py index 83d9d8c..ca316bd 100644 --- a/tee_gateway/definitions.py +++ b/tee_gateway/definitions.py @@ -19,8 +19,9 @@ # Network IDs (EIP-155 chain identifiers) # --------------------------------------------------------------------------- -# Base Testnet — where OPG payments are accepted -BASE_TESTNET_NETWORK: str = "eip155:84532" + +# Base Mainnet — where OPG payments are accepted +BASE_MAINNET_NETWORK: str = "eip155:8453" # --------------------------------------------------------------------------- # Payment recipient @@ -31,15 +32,15 @@ # your own instance. EVM_PAYMENT_ADDRESS: str = os.getenv( "EVM_PAYMENT_ADDRESS", - "0x40eFb45552EDfB2502D90A657a8ab41F03ec460d", + "0x9deEBB5D1b22e4a6e027977CeAd13893A7E4cC1a", ) # --------------------------------------------------------------------------- # ERC-20 token contract addresses # --------------------------------------------------------------------------- -# OpenGradient token (OPG) on Base Testnet -BASE_OPG_ADDRESS: str = "0x240b09731D96979f50B2C649C9CE10FcF9C7987F" +# OpenGradient token (OPG) on Base Mainnet +BASE_MAINNET_OPG_ADDRESS: str = "0xFbC2051AE2265686a469421b2C5A2D5462FbF5eB" # --------------------------------------------------------------------------- # Token decimal places @@ -47,7 +48,7 @@ # Maps lowercase contract address → number of decimals for unit conversion. ASSET_DECIMALS_BY_ADDRESS: dict[str, int] = { - BASE_OPG_ADDRESS.lower(): 18, # OPG: 18 decimals (ERC-20 standard) + BASE_MAINNET_OPG_ADDRESS.lower(): 18, # OPG: 18 decimals (ERC-20 standard) } # Fallback for any asset not explicitly listed above diff --git a/tests/test_pricing.py b/tests/test_pricing.py index 2f3ed90..d1b5f25 100644 --- a/tests/test_pricing.py +++ b/tests/test_pricing.py @@ -11,7 +11,7 @@ import unittest from decimal import Decimal -from tee_gateway.definitions import BASE_OPG_ADDRESS +from tee_gateway.definitions import BASE_MAINNET_OPG_ADDRESS from tee_gateway.model_registry import ( _MODEL_LOOKUP, get_model_config, @@ -26,7 +26,7 @@ def _opg_requirements() -> dict: """Fake PaymentRequirements dict for OPG (18 decimals).""" - return {"asset": BASE_OPG_ADDRESS, "amount": "50000000000000000"} + return {"asset": BASE_MAINNET_OPG_ADDRESS, "amount": "50000000000000000"} def _ctx(model: str, input_tokens: int, output_tokens: int, requirements=None) -> dict: diff --git a/uv.lock b/uv.lock index af18737..bfb2691 100644 --- a/uv.lock +++ b/uv.lock @@ -1242,17 +1242,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, +] + [[package]] name = "og-x402" -version = "0.0.1.dev6" +version = "0.0.1.dev9" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "nest-asyncio" }, { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/70/aa/2b616b9be6dfa4dfee98bde3ed20dd41cb446d0569e0069c1d6c11faa032/og_x402-0.0.1.dev6.tar.gz", hash = "sha256:140c4b725f372e81f4a3c2caf392f58b6fcf242bc51a1c3a6417f58e3ef9e347", size = 900115, upload-time = "2026-03-30T07:13:25.623Z" } +sdist = { url = "https://files.pythonhosted.org/packages/97/f5/02e7b68af825c200da2aa88292f2c07823d321a4fd9e2a3d20130358fc10/og_x402-0.0.1.dev9.tar.gz", hash = "sha256:d3cfd05443636712cb1277e3d904b878d875a60b3728d64265098ea06eeb116b", size = 1312652, upload-time = "2026-04-10T10:40:13.267Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/5e/a64de6f29eb80bb180288297882d5aba2a894363622d4f94417b420cf0b5/og_x402-0.0.1.dev6-py3-none-any.whl", hash = "sha256:2a1f962fa2a50d02f28421199027245d5c5f013f36a143ec2f184a546325f1bd", size = 952670, upload-time = "2026-03-30T07:13:00.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/08/f5a05fc8454541e96650d44bf15b34491505d0e4f1e9e77b26c804fbbdd3/og_x402-0.0.1.dev9-py3-none-any.whl", hash = "sha256:2db171be2526aa13a1243255538d185c4f1f6106f615eff532d1720a89672034", size = 1392934, upload-time = "2026-04-10T10:40:11.224Z" }, ] [package.optional-dependencies] @@ -1881,7 +1891,7 @@ requires-dist = [ { name = "langchain-google-genai", specifier = ">=4.2.1" }, { name = "langchain-openai", specifier = ">=1.1.12" }, { name = "langchain-xai", specifier = ">=1.2.2" }, - { name = "og-x402", extras = ["evm"], specifier = "==0.0.1.dev6" }, + { name = "og-x402", extras = ["evm"], specifier = ">=0.0.1.dev9" }, { name = "openai", specifier = ">=2.15.0" }, { name = "psutil", specifier = ">=7.2.1" }, { name = "pydantic", specifier = ">=2.12.5" },