Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
39 changes: 25 additions & 14 deletions tee_gateway/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand All @@ -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",
),
Expand All @@ -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",
),
Expand Down Expand Up @@ -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
)

Expand Down
13 changes: 7 additions & 6 deletions tee_gateway/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -31,23 +32,23 @@
# 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
# ---------------------------------------------------------------------------

# 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
Expand Down
4 changes: 2 additions & 2 deletions tests/test_pricing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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:
Expand Down
18 changes: 14 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading