diff --git a/examples/python/clients/README.md b/examples/python/clients/README.md index 94477efab4..0fdcf97f5b 100644 --- a/examples/python/clients/README.md +++ b/examples/python/clients/README.md @@ -8,6 +8,7 @@ This directory contains examples demonstrating how to use the x402 v2 SDK with d |-----------|-------------|---------| | [httpx/](./httpx/) | httpx | Async | | [requests/](./requests/) | requests | Sync | +| [agentshare/](./agentshare/) | httpx | Async POST to a live x402 seller (AgentShare Meteora) | ## Quick Start diff --git a/examples/python/clients/agentshare/.env-local b/examples/python/clients/agentshare/.env-local new file mode 100644 index 0000000000..b0d43f2b25 --- /dev/null +++ b/examples/python/clients/agentshare/.env-local @@ -0,0 +1,3 @@ +EVM_PRIVATE_KEY= +RESOURCE_SERVER_URL=https://agentshare.dev +ENDPOINT_PATH=/api/v1/agent/defi/meteora/brief diff --git a/examples/python/clients/agentshare/README.md b/examples/python/clients/agentshare/README.md new file mode 100644 index 0000000000..7c5012e070 --- /dev/null +++ b/examples/python/clients/agentshare/README.md @@ -0,0 +1,40 @@ +# AgentShare × x402 (Meteora brief) + +Pay for live Solana DeFi intelligence from [AgentShare](https://agentshare.dev) +using the official x402 Python buyer SDK. + +- Endpoint: `POST /api/v1/agent/defi/meteora/brief` +- Settlement today: **Base mainnet** (`eip155:8453`) USDC via Circle Gateway +- Pricing: **dynamic** ~$0.01–$0.30 USDC (read live quote from HTTP 402) + +## Setup + +```bash +cp .env-local .env +# Set EVM_PRIVATE_KEY to a Base wallet funded with USDC +uv sync +uv run python main.py +``` + +Or with pip: + +```bash +pip install "x402[httpx]" eth-account python-dotenv +export EVM_PRIVATE_KEY=0x... +python main.py +``` + +## Environment + +| Variable | Description | +|----------|-------------| +| `EVM_PRIVATE_KEY` | EVM private key (Base / mainnet USDC) | +| `RESOURCE_SERVER_URL` | Default `https://agentshare.dev` | +| `ENDPOINT_PATH` | Default `/api/v1/agent/defi/meteora/brief` | + +## Links + +- Discovery: https://agentshare.dev/.well-known/x402 +- OpenAPI: https://agentshare.dev/openapi.json +- x402scan listing: https://www.x402scan.com/server/65b3e822-068a-4e51-a8bb-2ade6d5f0b32 +- Standalone copy: https://github.com/anhmtk/agentshare-mcp/blob/main/examples/buy_meteora_x402.py diff --git a/examples/python/clients/agentshare/main.py b/examples/python/clients/agentshare/main.py new file mode 100644 index 0000000000..7afe89305d --- /dev/null +++ b/examples/python/clients/agentshare/main.py @@ -0,0 +1,78 @@ +"""Buy AgentShare Meteora DLMM brief with x402 (USDC on Base mainnet). + +AgentShare is a live Solana DeFi intelligence API. Unpaid calls return HTTP 402; +this example uses the official x402 httpx client to sign and retry automatically. + +Seller discovery: https://agentshare.dev/.well-known/x402 +x402scan: https://www.x402scan.com/server/65b3e822-068a-4e51-a8bb-2ade6d5f0b32 +""" + +from __future__ import annotations + +import asyncio +import json +import os +import sys + +from dotenv import load_dotenv +from eth_account import Account + +from x402 import x402Client +from x402.http import x402HTTPClient +from x402.http.clients import x402HttpxClient +from x402.mechanisms.evm import EthAccountSigner +from x402.mechanisms.evm.exact.register import register_exact_evm_client + +load_dotenv() + + +def validate_environment() -> tuple[str, str, str]: + evm_private_key = (os.getenv("EVM_PRIVATE_KEY") or "").strip() + base_url = (os.getenv("RESOURCE_SERVER_URL") or "https://agentshare.dev").rstrip("/") + endpoint_path = ( + os.getenv("ENDPOINT_PATH") or "/api/v1/agent/defi/meteora/brief" + ).strip() + + if not evm_private_key: + print("Error: set EVM_PRIVATE_KEY (Base mainnet wallet with USDC).") + print("Copy .env-local to .env and fill in values.") + sys.exit(1) + + return evm_private_key, base_url, endpoint_path + + +async def main() -> None: + evm_private_key, base_url, endpoint_path = validate_environment() + + client = x402Client() + account = Account.from_key(evm_private_key) + register_exact_evm_client(client, EthAccountSigner(account)) + http_helper = x402HTTPClient(client) + + url = f"{base_url}{endpoint_path}" + body = {"limit": 3, "window": "5m", "format": "compact"} + print(f"Buyer: {account.address}") + print(f"POST {url}") + print(f"Body: {body}\n") + + async with x402HttpxClient(client) as http: + response = await http.post(url, json=body) + await response.aread() + + print(f"Response status: {response.status_code}") + try: + print(json.dumps(response.json(), indent=2, ensure_ascii=False)[:4000]) + except Exception: + print(response.text[:4000]) + + try: + settle = http_helper.get_payment_settle_response( + lambda name: response.headers.get(name) + ) + print("\nPayment response:", settle.model_dump_json(indent=2)) + except ValueError: + print("\nNo PAYMENT-RESPONSE header found") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/python/clients/agentshare/pyproject.toml b/examples/python/clients/agentshare/pyproject.toml new file mode 100644 index 0000000000..b5525b5623 --- /dev/null +++ b/examples/python/clients/agentshare/pyproject.toml @@ -0,0 +1,25 @@ +[project] +name = "x402-agentshare-example" +version = "0.1.0" +description = "Buy AgentShare Meteora brief with x402 (Base USDC)" +requires-python = ">=3.10" +dependencies = [ + "python-dotenv>=1.0.0", + "x402[httpx,evm]", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.uv] +package = false + +[tool.uv.sources] +x402 = { path = "../../../../python/x402", editable = true }