Skip to main content

venice_ai.auth.x402

x402 Sign-In-With-X (SIWE / EIP-4361) authentication for Venice's /x402/* endpoints.

The API requires an X-Sign-In-With-X header — a base64-encoded JSON payload proving ownership of an Ethereum wallet on Base (chain 8453).

Usage:

from venice_ai.auth.x402 import X402Auth

auth = X402Auth(private_key="0xabc...")
# auth.wallet_address — checksummed address derived from the key
# auth.build_header() — returns the base64 value for ``X-Sign-In-With-X``

This module is optional and requires ``pip install venice-ai[x402]``.

X402Auth Objects

class X402Auth()

Builds X-Sign-In-With-X tokens for Venice's x402 endpoints.

Arguments:

  • private_key: Ethereum private key as hex string (0x-prefixed or bare 64 hex chars). Never share or commit this.
  • chain_id: Chain ID; defaults to Base mainnet (8453).
  • ttl_seconds: SIWE message TTL from issuedAt to expirationTime. Defaults to 600 s (10 min) per the Venice docs.

X402Auth.wallet_address

@property
def wallet_address() -> str

Checksummed Ethereum address derived from the private key.

X402Auth.ttl_seconds

@property
def ttl_seconds() -> int

SIWE token TTL in seconds (default 600).

X402Auth.chain_id

@property
def chain_id() -> int

EVM chain ID this auth was constructed for (default 8453, Base mainnet).

X402Auth.build_header

def build_header(*,
nonce: str | None = None,
now: datetime | None = None) -> str

Build the base64-encoded X-Sign-In-With-X header value.

Arguments:

  • nonce: Optional 16-character hex nonce; a cryptographically random one is generated if omitted.
  • now: Override the issuedAt timestamp (UTC). Useful for testing / cassette recording. Defaults to datetime.now(UTC).

X402Auth.build_payment_header

def build_payment_header(requirement: dict[str, Any],
*,
validate_network: str = "eip155:8453",
validate_asset: str | None = None,
max_amount_units: int | None = None,
valid_for_seconds: int = 600,
nonce: str | None = None,
now: datetime | None = None) -> str

Build the base64-encoded X-402-Payment v2 envelope from a 402 requirement.

Constructs the EIP-712 typed data for USDC transferWithAuthorization, signs with this auth's private key, and base64-encodes the v2 payment envelope ready for :meth:venice_ai.resources.x402.X402.top_up.

Validates network, asset, and amount BEFORE signing — refuses to sign payloads that deviate from expectations. This is a security control: a misbehaving or malicious server could otherwise ask you to sign a transfer to an attacker-controlled address.

Currently supports only USDC on Base mainnet (eip155:8453). Other tokens / chains would need different EIP-712 domain parameters (name, version); extending this helper to accept overrides is future work.

Arguments:

  • requirement: A single requirement dict from PaymentRequiredError.body["accepts"][i]. Expected keys: network (CAIP-2 chain id), asset (ERC-20 contract address), amount (string in token base units), payTo (recipient address). Optional scheme (defaults to "exact").
  • validate_network: Refuse if requirement["network"] doesn't match. Default "eip155:8453" (Base mainnet).
  • validate_asset: Optional asset contract address (case-insensitive). When None (default), the asset is checked against :data:USDC_BASE_MAINNET. Pass an explicit address to allow another asset; you'll also need EIP-712 domain support which is not currently exposed.
  • max_amount_units: Optional cap in token base units (USDC has 6 decimals, so 5_000_000 = 5 USDC). Refuses to sign if int(requirement["amount"]) exceeds this. None disables the cap (not recommended in production).
  • valid_for_seconds: validBefore window from now. Default 600s (10 min) — long enough to cover network round-trip and server processing, short enough to limit replay surface.
  • nonce: Optional 32-byte hex nonce (with or without 0x prefix). Generated cryptographically when None. Override only for testing / cassette recording. Re-using a nonce is rejected server-side — generate a fresh one per call.
  • now: Optional UTC datetime override for validBefore computation. Defaults to datetime.now(UTC). Override for testing.

Raises:

  • ValueError: On validation mismatch (network, asset, amount) or malformed requirement (missing required keys).
  • ImportError: If the [x402] extra isn't installed (raised at module import time, not here, but documented for completeness).

Example:

from venice_ai.auth.x402 import X402Auth
from venice_ai.exceptions import PaymentRequiredError

auth = X402Auth(private_key=os.environ["WALLET_PRIVATE_KEY"])
try:
await client.x402.top_up()
except PaymentRequiredError as e:
requirement = e.body["accepts"][0]
header = auth.build_payment_header(
requirement,
max_amount_units=10_000_000, # cap at $10
)
result = await client.x402.top_up(payment_header=header)
print(result.data.amountCredited)

Returns:

Base64-encoded v2 X-402-Payment envelope string.