Awesome-omni-skill atp
Create ATP Protocol servers (FastAPI + middleware) and clients. Use when building ATP-protected APIs, adding payment middleware, or writing clients that call ATP endpoints or the settlement service.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/atp" ~/.claude/skills/diegosouzapw-awesome-omni-skill-atp && rm -rf "$T"
skills/development/atp/SKILL.mdATP Protocol skill – servers and clients
Use this skill when you need to create or modify ATP (Agent Trade Protocol) servers or clients. ATP enables agent-to-agent payments on Solana: middleware on the server charges by token usage; the client pays and receives decrypted responses after settlement.
Documentation index: For full Claude Code docs (skills, agents, etc.), fetch: https://code.claude.com/docs/llms.txt
1. Creating an ATP server
1.1 Minimal FastAPI server with ATP middleware
- Use FastAPI and add
so selected endpoints are paid per use.ATPSettlementMiddleware - Endpoints must return usage data (input/output token counts) in a supported format so the middleware can compute and execute payment.
Imports and app:
from fastapi import FastAPI from fastapi.responses import JSONResponse from atp.middleware import ATPSettlementMiddleware from atp.schemas import PaymentToken app = FastAPI(title="My ATP-Protected API")
Add middleware (required args):
app.add_middleware( ATPSettlementMiddleware, allowed_endpoints=["/v1/chat", "/v1/completions"], # exact path list input_cost_per_million_usd=10.0, # USD per million input tokens output_cost_per_million_usd=30.0, # USD per million output tokens recipient_pubkey="YourSolanaWalletPublicKeyHere", # required; receives payment payment_token=PaymentToken.SOL, # SOL or PaymentToken.USDC )
Optional middleware args:
: Header name for wallet key (defaultwallet_private_key_header
)."x-wallet-private-key"
: Skip Solana preflight (defaultskip_preflight
).False
: Solana commitment (defaultcommitment
)."confirmed"
: Facilitator URL (default fromsettlement_service_url
orATP_SETTLEMENT_URL
).https://facilitator.swarms.world
: Iffail_on_settlement_error
, raise on settlement failure (defaultTrue
).False
: Timeout in seconds (default from env orsettlement_timeout
).300.0
Protected endpoint example (return usage):
@app.post("/v1/chat") async def chat(request: dict): message = request.get("message", "") # Your agent logic response_text = "Agent response here" return JSONResponse(content={ "response": response_text, "usage": { "input_tokens": 100, "output_tokens": 50, "total_tokens": 150 } })
Supported usage formats (middleware/settlement parses these):
- OpenAI:
,usage.prompt_tokens
,usage.completion_tokensusage.total_tokens - Anthropic:
,usage.input_tokensusage.output_tokens - Google/Gemini:
,usageMetadata.promptTokenCount
,candidatesTokenCounttotalTokenCount
Paths not in
allowed_endpoints are not charged (e.g. /v1/health).
Run server:
if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)
1.2 Server checklist
- Set
to the Solana wallet that should receive payments.recipient_pubkey - Ensure every protected handler returns a body that includes one of the supported usage structures.
- Optional: set
(base64 Fernet) for consistent response encryption across restarts; otherwise a key is generated per process.ATP_ENCRYPTION_KEY - For production: use
and checkfail_on_settlement_error=False
on the client; never log or persist wallet private keys.atp_settlement_status
2. Creating an ATP client
2.1 Client for ATP-protected endpoints
Use
to call ATP-protected APIs: it adds the wallet header and can decrypt responses after payment.ATPClient
Imports and constructor:
from atp.client import ATPClient client = ATPClient( wallet_private_key="[1,2,3,...]", # or base58 string; required for payment settlement_service_url="https://facilitator.swarms.world", # optional settlement_timeout=300.0, # optional wallet_private_key_header="x-wallet-private-key", # optional verbose=False, # optional, for debugging )
Making a paid request (POST):
import asyncio response = asyncio.run(client.post( url="https://api.example.com/v1/chat", json={"message": "Hello!"}, # wallet_private_key=..., # optional override per request # auto_decrypt=True, # default True )) print(response["response"]) # agent output print(response.get("atp_settlement")) # payment details print(response.get("atp_settlement_status")) # e.g. "paid" or "failed"
GET and other methods:
response = await client.get(url="https://api.example.com/v1/status") response = await client.request("PUT", url=some_url, json=payload)
If
auto_decrypt=True (default), the client decrypts encrypted response bodies when payment has succeeded.
2.2 Client for settlement service (facilitator) only
Use the same
for facilitator operations without calling an ATP-protected API.ATPClient
Health check (no wallet needed):
client = ATPClient() health = asyncio.run(client.health_check())
Parse usage (no wallet needed):
from atp.client import ATPClient import asyncio client = ATPClient() usage = asyncio.run(client.parse_usage({"usage": {"prompt_tokens": 100, "completion_tokens": 50, "total_tokens": 150}})) # usage -> e.g. {"input_tokens": 100, "output_tokens": 50, "total_tokens": 150}
Calculate payment (no blockchain call):
from atp.schemas import PaymentToken payment = await client.calculate_payment( usage={"input_tokens": 1000, "output_tokens": 500}, input_cost_per_million_usd=10.0, output_cost_per_million_usd=30.0, recipient_pubkey="RecipientPublicKeyHere", payment_token=PaymentToken.SOL, )
Execute settlement (spends SOL/USDC):
result = await client.settle( usage={"input_tokens": 1000, "output_tokens": 500}, input_cost_per_million_usd=10.0, output_cost_per_million_usd=30.0, recipient_pubkey="RecipientPublicKeyHere", payment_token=PaymentToken.SOL, ) # result includes tx_signature, status, etc.
2.3 Client checklist
- For paid endpoint calls or
, providesettle()
(constructor or per call).wallet_private_key - Wallet key format: JSON array string
or base58 keypair string."[1,2,3,...]" - Check
in responses to handle failures; never log or store private keys.atp_settlement_status - Env vars (optional):
,ATP_SETTLEMENT_URL
,ATP_SETTLEMENT_TIMEOUT
,ATP_WALLET_PRIVATE_KEY
.ATP_ENDPOINT_URL
3. Project layout and references
- Server examples:
,examples/server/example.pyexamples/server/full_flow_example.py - Client examples:
,examples/client/example_request.py
,examples/client/example_settle.pyexamples/client/example_health_check.py - API reference:
(middleware),atp/middleware.py
(client),atp/client.py
(atp/schemas.py
, config models)PaymentToken - Docs: README.md in repo; full docs at https://docs.swarms.ai/docs/atp/overview
When creating or editing ATP servers or clients, follow the patterns above and use the existing examples and atp package as the source of truth.