| """x402 Python SDK — pay-per-call AI tool access. |
| |
| Usage: |
| pip install x402-sdk |
| |
| from x402_sdk import x402 |
| |
| # Initialize |
| client = x402(api_key="your-key") |
| # or without API key (free trials only) |
| client = x402() |
| |
| # List available tools |
| tools = client.list_tools(category="intelligence") |
| for t in tools: |
| print(f"{t['id']}: ${t['price_usd']}") |
| |
| # Create invoice and get payment challenge |
| invoice = client.create_invoice(tool="token_scan") |
| |
| # Pay on-chain (user connects wallet, sends USDC) |
| # Then verify: |
| result = client.verify_payment( |
| tx_hash="0x...", |
| tool="token_scan", |
| ) |
| print(f"Verified: {result['verified']}") |
| |
| # Check balance and usage |
| balance = client.check_balance() |
| usage = client.get_usage(days=7) |
| """ |
|
|
| from __future__ import annotations |
|
|
| import json |
| from dataclasses import dataclass, field |
| from typing import Any, Optional |
|
|
| import httpx |
|
|
|
|
| @dataclass |
| class Invoice: |
| id: str |
| tool: str |
| amount_usd: float |
| amount_wei: int |
| pay_to: str |
| chain: str |
| signature: str |
| created_at: str |
| expires_at: float |
|
|
|
|
| @dataclass |
| class VerificationResult: |
| verified: bool |
| tx_hash: str = "" |
| tool: str = "" |
| amount_usd: float = 0.0 |
| chain: str = "" |
| payer: str = "" |
|
|
|
|
| @dataclass |
| class ToolInfo: |
| id: str |
| price_usd: float |
| category: str |
| trials: int |
| description: str = "" |
|
|
|
|
| class x402: |
| """x402 client — pay-per-call AI tool access. |
| |
| Args: |
| api_key: Optional API key for authenticated access. |
| base_url: x402 gateway URL (default: https://mcp.rugmunch.io) |
| """ |
|
|
| def __init__(self, api_key: str = "", base_url: str = "https://mcp.rugmunch.io"): |
| self.api_key = api_key |
| self.base_url = base_url.rstrip("/") |
| self._http = httpx.Client( |
| headers={"X-API-Key": api_key} if api_key else {}, |
| timeout=30, |
| ) |
|
|
| def list_tools(self, category: str = "") -> list[ToolInfo]: |
| """List all available x402 tools with prices and trial info. |
| |
| Args: |
| category: Optional filter (intelligence, premium, monitoring, etc.) |
| |
| Returns: |
| List of ToolInfo with id, price_usd, category, trials, description |
| """ |
| params = {} |
| if category: |
| params["category"] = category |
| r = self._http.post( |
| f"{self.base_url}/mcp/x402", |
| json={"method": "tools/call", "params": {"name": "x402_list_tools", "arguments": params}}, |
| ) |
| data = r.json().get("result", {}) |
| text = json.loads(data.get("content", [{}])[0].get("text", "{}")) |
| return [ToolInfo(**t) for t in text.get("tools", [])] |
|
|
| def create_invoice(self, tool: str, agent_id: str = "") -> Invoice: |
| """Create a payment challenge for a tool. |
| |
| Returns an invoice with amount, pay_to address, chain, and HMAC |
| signature. Pay on-chain, then call verify_payment(). |
| |
| Args: |
| tool: Tool ID (e.g., 'token_scan', 'rug_probability') |
| agent_id: Optional agent identifier |
| |
| Returns: |
| Invoice with payment details |
| """ |
| r = self._http.post( |
| f"{self.base_url}/mcp/x402", |
| json={ |
| "method": "tools/call", |
| "params": { |
| "name": "x402_create_invoice", |
| "arguments": {"tool": tool, "agent_id": agent_id or ""}, |
| }, |
| }, |
| ) |
| data = r.json().get("result", {}) |
| text = json.loads(data.get("content", [{}])[0].get("text", "{}")) |
| return Invoice(**text) |
|
|
| def verify_payment(self, tx_hash: str, tool: str, amount_usd: float = 0) -> VerificationResult: |
| """Verify an on-chain payment. |
| |
| Once verified, the caller is authorized to use the tool. |
| |
| Args: |
| tx_hash: Transaction hash from the on-chain payment |
| tool: Tool ID that was paid for |
| amount_usd: Expected payment amount |
| |
| Returns: |
| VerificationResult with verification status |
| """ |
| r = self._http.post( |
| f"{self.base_url}/mcp/x402", |
| json={ |
| "method": "tools/call", |
| "params": { |
| "name": "x402_verify_payment", |
| "arguments": {"tx_hash": tx_hash, "tool": tool, "amount_usd": amount_usd}, |
| }, |
| }, |
| ) |
| data = r.json().get("result", {}) |
| text = json.loads(data.get("content", [{}])[0].get("text", "{}")) |
| return VerificationResult(**text) |
|
|
| def check_balance(self, agent_id: str = "") -> dict: |
| """Check remaining free trials and usage. |
| |
| Args: |
| agent_id: Agent identifier |
| |
| Returns: |
| Dict with balances per tool |
| """ |
| r = self._http.post( |
| f"{self.base_url}/mcp/x402", |
| json={ |
| "method": "tools/call", |
| "params": { |
| "name": "x402_check_balance", |
| "arguments": {"agent_id": agent_id or "sdk_user"}, |
| }, |
| }, |
| ) |
| data = r.json().get("result", {}) |
| return json.loads(data.get("content", [{}])[0].get("text", "{}")) |
|
|
| def get_usage(self, agent_id: str = "", days: int = 7) -> dict: |
| """View usage history and spending. |
| |
| Args: |
| agent_id: Agent identifier |
| days: Days of history |
| |
| Returns: |
| Dict with usage stats |
| """ |
| r = self._http.post( |
| f"{self.base_url}/mcp/x402", |
| json={ |
| "method": "tools/call", |
| "params": { |
| "name": "x402_get_usage", |
| "arguments": {"agent_id": agent_id or "sdk_user", "days": days}, |
| }, |
| }, |
| ) |
| data = r.json().get("result", {}) |
| return json.loads(data.get("content", [{}])[0].get("text", "{}")) |
|
|