internal/embed/skills/monetize-guide/SKILL.md
End-to-end guide for monetizing GPU resources or HTTP services through obol-stack. Covers pre-flight checks, model detection, pricing research, selling via x402, ERC-8004 registration, and verification. Use this skill when the user wants to monetize their machine.
npx skillsauth add obolnetwork/obol-stack monetize-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Step-by-step guide to expose local GPU resources or HTTP services as x402 payment-gated endpoints with on-chain discovery via ERC-8004.
sell directlybuy-x402obol-stackFollow these phases in order. Stop and ask the user for confirmation before executing phase 4.
Verify the environment is ready before proceeding.
# 1. Check cluster is running
obol kubectl get nodes
# 2. Check the agent is initialized (has RBAC for monetization)
obol kubectl get clusterrolebinding openclaw-monetize-read-binding -o jsonpath='{.subjects}'
# 3. Get the wallet address (auto-generated by agent)
python3 ${OBOL_SKILLS_DIR:-/data/.openclaw/skills}/ethereum-local-wallet/scripts/signer.py accounts
If cluster is not running: Tell the user to run obol stack up first. Do NOT run it yourself — it takes several minutes and changes system state.
If agent has no RBAC subjects: Tell the user to run obol agent init.
If no wallet address: The wallet is created during obol stack up. If missing, the stack may not have completed setup.
# Check what Ollama models are available locally
curl -s http://localhost:11434/api/tags | python3 -c "
import json, sys
data = json.load(sys.stdin)
for m in data.get('models', []):
size_gb = m.get('size', 0) / 1e9
print(f\" {m['name']:30s} {size_gb:.1f} GB\")
"
Report the available models to the user. If no models are found, suggest they pull one:
ollama pull qwen3.5:4b # Smallest current Qwen, ~3.4 GB (low-RAM laptops)
ollama pull qwen3.5:9b # Validated baseline, ~6.6 GB
ollama pull qwen3.6:27b # High quality, ~17 GB (needs ≥32GB RAM)
Ask the user if they have a GPU server or inference endpoint on their local network. If yes, get:
http://192.168.0.202:8000/v1)Verify it's reachable and OpenAI-compatible:
# Probe the external endpoint
curl -s <ENDPOINT_URL>/models | python3 -c "
import json, sys
data = json.load(sys.stdin)
for m in data.get('data', []):
print(f\" {m['id']}\")
"
If reachable, this endpoint can be sold by bridging it through LiteLLM (see Phase 4).
# List services in the cluster that could be monetized
obol kubectl get svc -A --no-headers | grep -v 'kube-system\|traefik\|x402\|monitoring\|erpc\|obol-frontend'
Ask the user which service they want to expose and on which port.
Query the ERC-8004 registry to see what comparable services charge.
# Search for registered agents on Base Sepolia
python3 ${OBOL_SKILLS_DIR:-/data/.openclaw/skills}/discovery/scripts/discovery.py search --limit 10
# For each agent with x402Support, fetch their registration to see pricing
python3 ${OBOL_SKILLS_DIR:-/data/.openclaw/skills}/discovery/scripts/discovery.py uri <agent_id>
Pricing guidelines (present these to the user with your research):
| Service Type | Typical Range | Notes | |-------------|---------------|-------| | LLM inference (small, <4B) | 0.0005–0.002 USDC/req | Fast, low compute | | LLM inference (medium, 4-14B) | 0.001–0.005 USDC/req | Good quality/cost balance | | LLM inference (large, >14B) | 0.005–0.02 USDC/req | High quality, slower | | Data API / indexer | 0.0001–0.001 USDC/req | Depends on query complexity | | Compute-heavy (GPU hours) | 0.10–1.00 USDC/hour | Fine-tuning, training |
Always present your research and recommendation to the user and ask them to confirm the price before proceeding.
Only proceed after the user has confirmed the price.
obol sell inference <name> \
--model <model_name> \
--price <confirmed_price> \
--register-name "<descriptive name>" \
--register-description "<what the model does>" \
--register-skills natural_language_processing/natural_language_generation/text_completion \
--register-domains technology/data_science
The --wallet and --chain will be auto-resolved (remote-signer wallet, base-sepolia default).
Two steps: first bridge the endpoint into LiteLLM, then sell LiteLLM.
# Step A: Add the external endpoint to LiteLLM
obol model setup custom \
--endpoint <full_url_with_v1> \
--model "<model_name_at_endpoint>"
# Step B: Sell it through LiteLLM
obol sell http <name> \
--upstream litellm \
--port 4000 \
--namespace llm \
--per-request <confirmed_price> \
--wallet <wallet_address> \
--chain base-sepolia \
--health-path /health/liveliness \
--register-name "<descriptive name>" \
--register-description "<what the service does>" \
--register-skills natural_language_processing/natural_language_generation/text_completion \
--register-domains technology/data_science
The --endpoint must include /v1 if the upstream is an OpenAI-compatible server (vLLM, TGI, etc.) — LiteLLM does not append it automatically.
LAN IPs (e.g., http://192.168.0.202:8000/v1) are reachable from inside the k3d cluster without any additional network configuration.
obol sell http <name> \
--upstream <service_name> \
--namespace <namespace> \
--port <port> \
--per-request <confirmed_price> \
--chain base-sepolia \
--health-path <health_endpoint> \
--register-name "<descriptive name>" \
--register-description "<what the service does>" \
--register-skills <oasf_skill_path> \
--register-domains <oasf_domain_path>
obol sell http now registers by default. Use --no-register only for local
or private-only flows where on-chain discovery is intentionally skipped.
The agent reconciler automatically processes the ServiceOffer through 6 stages.
# Watch the conditions progress (check every 15 seconds, up to 2 minutes)
for i in $(seq 1 8); do
echo "--- Attempt $i ---"
obol sell status <name> -n <namespace> 2>&1 | grep -A1 'type:\|status:\|reason:\|message:'
sleep 15
done
Expected progression:
If a stage is stuck, check:
# Agent logs for reconciliation errors
obol kubectl logs -l app.kubernetes.io/name=hermes -n hermes-obol-agent --tail=50
# x402-verifier is running
obol kubectl get pods -n x402
# Get the tunnel URL
obol tunnel status
# Test the endpoint is live and payment-gated (should return 402 with pricing)
obol sell test <name> -n <namespace>
# Or manually:
TUNNEL_URL=$(obol tunnel status 2>&1 | grep -o 'https://[^ ]*')
curl -s -o /dev/null -w "%{http_code}" "$TUNNEL_URL/services/<name>/health"
# Expected: 402
# Inspect the 402 pricing response
curl -s "$TUNNEL_URL/services/<name>/health" | python3 -m json.tool
A 402 response with x402Version: 1 and an accepts array confirms the endpoint is live and payment-gated.
Present a summary:
Service monetized successfully!
Name: <name>
Model: <model> (if inference)
Price: <price> USDC per request
Chain: base-sepolia
Wallet: <wallet_address>
Endpoint: <tunnel_url>/services/<name>/v1/chat/completions
Registry: Agent #<id> on ERC-8004 (Base Sepolia)
Buyers can discover this service at:
<tunnel_url>/.well-known/agent-registration.json
To check status: obol sell status <name> -n <namespace>
To stop selling: obol sell stop <name> -n <namespace>
To delete: obol sell delete <name> -n <namespace>
Use these when registering for on-chain discovery:
Common skills:
natural_language_processing/natural_language_generation/text_completion — LLM chatnatural_language_processing/text_generation — general text generationdata_management/indexing — data indexing servicesdata_management/search — search servicesdevops_mlops/model_versioning — training/fine-tuningCommon domains:
technology/data_science — AI servicesresearch_and_development/scientific_research — ML researchtechnology/blockchain — blockchain data servicesobol stack up without explicit user request — it's a long-running infra changeobol stack down or obol stack purge — destructive operationsdata-ai
Spawn durable child Hermes agents from inside Obol Stack. Creates child namespaces, optional profile/env Secrets, Agent CRDs, and optional ServiceOffers for x402-paid child services.
data-ai
Buy from any x402-gated endpoint. Two flows: `pay` for one-shot HTTP services (single authorization, no sidecar), and `buy` for long-running paid inference (pre-authorized batch via PurchaseRequest, exposed as `paid/<remote-model>`). Supports USDC (EIP-3009) and OBOL (Permit2). Zero signer access at runtime — spending is capped by design and nothing moves on-chain until a voucher is spent.
testing
Sell access to services via x402 payment gating. Create ServiceOffer CRDs that automatically health-check upstreams, create payment-gated routes, and optionally pull models and register on ERC-8004. Supports inference, HTTP, and fine-tuning service types.
databases
Query Ethereum networks through the local RPC gateway. Use when asked about blocks, balances, transactions, gas prices, token balances, or any eth_* JSON-RPC method. All queries are read-only and routed through the in-cluster eRPC load balancer.