Infrastructure leasing demo built around x402 payments.
This repo contains three services:
backend-proxmox/: FastAPI paywalled API that provisions and manages Proxmox LXC containers (port4021).backend-llm/: FastAPI chat agent that calls the paywalled API. It acts as an orchestrator but delegates payment signing to the client (port8000).frontend/: Vite + React UI that calls the agent service and handles crypto payments via wallet connection (port3000).
- Python
3.10+ uv(Python dependency manager)- Node.js
18+ pnpm- Proxmox VE host + API token (to actually create/manage containers)
- An EVM address to receive payments (paywall configuration)
- A browser wallet (e.g., Coinbase Wallet) for the client-side user
- Coinbase Developer Platform API Key (for OnchainKit in the frontend)
Create backend-proxmox/.env (start from backend-proxmox/.example.env) and set at minimum:
ADDRESS: EVM address to receive paymentsNETWORK: EVM network name (defaults tobase-sepolia)
To enable Proxmox operations, also set:
PVE_HOST,PVE_TOKEN_ID,PVE_TOKEN_SECRET,PVE_NODE,PVE_STORAGE,PVE_OS_TEMPLATEPVE_ROOT_PASSWORD(used for console ticket flows)PVE_VERIFY_SSL(true/false)- Optional:
PVE_CONSOLE_HOST(external hostname for console URLs)
See backend-proxmox/PROXMOX_API_USAGE.md for the expected Proxmox-side permissions and endpoints.
Create backend-llm/.env (start from backend-llm/.example.env) and set:
LLM_PROVIDER:openaiorflockio- If
LLM_PROVIDER=openai:OPENAI_API_KEY - If
LLM_PROVIDER=flockio:FLOCKIO_API_KEY - Optional:
BACKEND_BASE_URL(defaults tohttp://localhost:4021)
Note: backend-llm/.example.env may not list all currently used variables; the server reads LLM_PROVIDER, OPENAI_API_KEY, and FLOCKIO_API_KEY.
Create frontend/.env with:
VITE_CHAT_API_BASE=http://localhost:8000
VITE_ONCHAINKIT_API_KEY=your_cdp_api_key
VITE_DEFAULT_NETWORK=base-sepolia
cd backend-proxmox
uv sync
uv run python main.py # http://localhost:4021cd backend-llm
uv sync
uv run python pydantic-server.py # http://localhost:8000cd frontend
pnpm install
pnpm dev # http://localhost:3000Agent service (no payment required):
GET /info: returns the configured LLM base URL + model name (and a masked API key)POST /chat: chat endpoint; the agent can call paid tools to manage leases. Returns apayment_requestobject if 402 is encountered.
Paywalled Proxmox service (x402 payment required):
POST /lease/containerPOST /lease/{ctid}/renewPOST /management/exec/{ctid}POST /management/console/{ctid}GET /management/list
For request/response examples and the payment flow, see backend-proxmox/API_USAGE.md.
Error: Request URL is missing an 'http://' or 'https://' protocol
Cause: PVE_HOST in backend-proxmox/.env is missing the protocol prefix.
Fix:
# ❌ Wrong
PVE_HOST="192.168.1.100:8006"
# ✅ Correct
PVE_HOST="https://192.168.1.100:8006"
PVE_CONSOLE_HOST="https://192.168.1.100:8006"Error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
Cause: Proxmox uses self-signed SSL certificates by default.
Fix: Disable SSL verification in backend-proxmox/.env:
PVE_VERIFY_SSL=falseProduction Alternative: Set up proper SSL certificates using Let's Encrypt:
# On Proxmox server
pvenode acme account register default your-email@example.com
pvenode config set --acme domains=proxmox.yourdomain.com
pvenode acme cert orderError: HTTP 595 or "Permission denied"
Cause: API token lacks required permissions.
Fix: Grant Administrator role to the token:
# On Proxmox server
pveum acl modify / -token 'root@pam!yourTokenID' -role Administrator
# Verify permissions
pveum user token permissions root@pam yourTokenIDRequired permissions:
VM.Allocate- Create containersVM.Config.*- Configure resourcesDatastore.AllocateSpace- Allocate storageSys.Console- Console access
Error: Container creation fails with 595 or "Node not found"
Cause: PVE_NODE doesn't match actual Proxmox node name.
Fix:
# Check actual node name
pvesh get /nodes
# Update backend-proxmox/.env
PVE_NODE="your-actual-node-name"Error: "Storage not found" or "Template not found"
Fix:
# Check available storage
pvesm status
# List templates
pveam list local
# Download Ubuntu template if missing
pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.zstIssue: Payment triggered multiple times, causing 500 errors.
Cause: Auto-payment useEffect and manual button click both trigger payment.
Fix: Already implemented in frontend/src/App.tsx using isProcessingPayment ref flag.
Issue: Coinbase Wallet doesn't pop up.
Fix:
- Install Coinbase Wallet browser extension
- Ensure wallet is on the correct network (check
VITE_DEFAULT_NETWORK) - Check browser console for errors
Issue: "Access to fetch blocked by CORS policy"
Fix: Ensure backend CORS settings allow frontend origin. In backend-llm/pydantic-server.py:
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000", "https://your-frontend-domain.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)Issue: Build fails with peer dependency errors.
Fix: Use --legacy-peer-deps flag in vercel.json:
{
"buildCommand": "cd frontend && npm install --legacy-peer-deps && npm run build"
}Issue: App can't connect to backend after deployment.
Fix: Set environment variables in Vercel dashboard:
VITE_CHAT_API_BASE- Your production backend URLVITE_ONCHAINKIT_API_KEY- CDP API keyVITE_DEFAULT_NETWORK- Network (base-sepolia or base)
- Secrets belong in
.envfiles and should not be committed. - The frontend is the entity that signs the payment headers using the connected wallet. The agent backend merely facilitates the negotiation.
- For production deployments, always use HTTPS and proper SSL certificates.
- Test thoroughly on testnet (base-sepolia) before deploying to mainnet.