A deterministic risk layer for autonomous trading agents.
Collar Guardrail provides deterministic, advisory risk checks for autonomous trading agents operating on Robinhood Chain.
deny response does not itself prevent an agent
from submitting a transaction on-chain. The integrating agent
is responsible for honoring the verdict.
Quickstart
Get up and running in under 2 minutes. This complete Python script demonstrates how to request a nonce, sign it, authenticate, and run a pre-trade risk check.
import requests
from eth_account import Account
from eth_account.messages import encode_defunct
# Configuration
BASE_URL = "https://backendai-x4m1.onrender.com"
PRIVATE_KEY = "0x..." # Your agent's private key
account = Account.from_key(PRIVATE_KEY)
wallet_address = account.address
# Step 1: Get authentication nonce
res = requests.get(f"{BASE_URL}/api/v1/auth/nonce", params={"address": wallet_address})
res.raise_for_status()
message_to_sign = res.json()["message"]
# Step 2: Sign EIP-191 message
message = encode_defunct(text=message_to_sign)
signature = Account.sign_message(message, private_key=PRIVATE_KEY).signature.hex()
# Step 3: Exchange signature for access token
auth_res = requests.post(f"{BASE_URL}/api/v1/auth/wallet", json={
"address": wallet_address,
"signature": signature
})
auth_res.raise_for_status()
token = auth_res.json()["access_token"]
# Step 4: Analyze a trade before submission
headers = {"Authorization": f"Bearer {token}"}
trade_payload = {
"wallet": wallet_address,
"asset": "NVDA",
"side": "buy",
"amount": 10.0,
"contract_address": "0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC",
"request_id": "quickstart-test-001"
}
trade_res = requests.post(f"{BASE_URL}/api/v1/analyze/trade", json=trade_payload, headers=headers)
print("Trade Verdict Response:", trade_res.json())
Why Collar exists
Robinhood Chain is a blockchain built for autonomous trading agents. Agents on it are fast, tireless, and increasingly handling real money.
They are also probabilistic. Every LLM-based agent can hallucinate a token address, ignore its own risk rules under pressure, or be talked into a bad trade by a prompt injection hidden in some piece of data it happened to read. When that happens, the agent does not stop. It executes.
The existing risk tooling was not built for this. Most platforms in the space use machine learning to monitor activity across many chains. That is the right model for institutional security. It is not designed for the independent agent developer who needs a deterministic second opinion in one HTTP call.
Collar does not try to be smarter than the agent. It tries to be predictable in a way the agent cannot be. It sits outside the agent's runtime, at the last point before a trade is signed, and returns one of three answers.
| Verdict | What it means |
|---|---|
| allow | No rule was violated. Proceed. |
| warn | Something is off — high risk score, nearing a limit, unusual frequency. Proceed with caution, or don't. |
| deny | A rule was violated. Do not submit the trade. The reason is in the response. |
When to use Collar
You're shipping an autonomous agent
Add one HTTP call before every trade. If the verdict is deny, don't sign. That's the entire integration.
You run a frontend or a bot
Call Collar before submitting a user's trade. Show the verdict in your UI. Turn a deny into a stop button.
You're a DeFi protocol
Use Collar as a second opinion before liquidations or large position changes. Deterministic verdicts are auditable.
You just want to see what happens
Hit the unauthenticated demo endpoint, or connect a wallet in preview mode. No COLR required pre-launch.
How Collar differs
There are already tools that watch on-chain activity. Most of them are excellent — for their intended audience. Collar is built around four choices that put it in a different shape.
| Design choice | What it means |
|---|---|
| REST API, not MCP-only | Most agent guardrails ship as MCP servers, which only work for agents whose client speaks MCP. Collar exposes both: a plain HTTP REST API for any agent, plus an MCP endpoint at /mcp-http/mcp for MCP-native clients. |
| Deterministic, not ML | Most risk platforms use machine learning. That is the right model for institutional security. It is not the right model for a guardrail that needs to be predictable. Collar uses fixed rules. Same input, same output. |
| Advisory, not enforced | Collar returns a verdict. It does not, today, block a transaction at the sequencer level. The integrating agent is responsible for honoring a deny. Stated plainly so no one assumes a guarantee that isn't there yet. |
| Stock-Token aware | Robinhood Chain's tokenized equities have failure modes generic tools don't model: corporate actions that pause the oracle, weekend staleness, multiplier adjustments. Collar reads oraclePaused() and applies stock-specific staleness windows including the full US holiday calendar. |
| Anti-rotation | Rate limits and daily-loss checks are enforced per wallet cluster, not per address. Deriving a fresh wallet funded from the same source does not reset either counter — the cluster fingerprint follows the funding graph. |
Collar is not claiming to be the first risk tool on Robinhood Chain. It is claiming to be a specific shape of one: API-first, deterministic, and stock-token aware.
Overview
Collar evaluates trade requests against a deterministic policy before the integrating agent submits them for execution. Each request is checked against:
- USD trade notional limits based on wallet COLR tier.
- Real-time Chainlink oracle prices for the traded asset.
- Uniswap V4 pool prices as a fallback when the oracle is unavailable.
- Corporate-action pause state (
oraclePaused()) for tokenized equities. - Feed staleness relative to heartbeat, including US market hours and holidays.
- Oracle-vs-pool divergence (slippage / MEV guard).
- Asset restrictions configured for eligible tiers.
- Cluster-based request frequency (runaway-agent detection).
- Cluster-based 24h P&L (daily-loss guardrail).
- Contract-address mismatch against the official registry.
- Honeypot heuristics for unregistered tokens.
COLR is an access and tier-gating token
COLR is not the trade currency. Agents can submit trades involving other supported assets, such as ETH, USDG, or tokenized equities. The wallet's COLR balance determines the access tier:
| Tier | COLR balance | Maximum trade value |
|---|---|---|
| TIER 1 | 1,000+ COLR | $5,000 USD |
| TIER 2 | 2,500+ COLR | $25,000 USD |
| TIER 3 | 5,000+ COLR | $100,000 USD |
While COLR has not launched, the API grants a default Tier 1 to every authenticated wallet. See preview-tier testing below.
Verdicts
| Decision | Meaning |
|---|---|
| allow | No configured rule violation was detected. Proceed. |
| warn | A potential runaway-agent pattern, elevated risk score, or nearing-limit condition. The integrating agent decides its own policy: log, slow down, or alert. |
| deny | One or more policy rules were violated. Do not submit the trade. Reasons are always included. |
Verdicts are advisory. Collar does not currently enforce the decision at the blockchain or sequencer level.
Price resolution
Every trade is priced by a strict resolution order. The first source that yields a valid price wins:
- Chainlink oracle — the primary source. The feed is rejected if
oraclePaused()is true, if the answer is zero or negative, or if it is older than the freshness window (120 s during US market hours). - Uniswap V4 pool — the fallback. If the oracle is unavailable, Collar reads the token's V4 pool directly. Registered assets also use this path; the contract address has already been validated against the official registry, so the pool we look up is for the real token.
- Refusal — if neither source produces a price, the verdict is
deny. Collar does not fall back to a hardcoded number: a fabricated price would make the tier-limit decision meaningless.
The price_source field in the response tells you which path was taken: oracle, uniswap_v4, or unavailable.
Slippage / MEV guard
When the reference price comes from the oracle, Collar also reads the live V4 pool spot price and compares them.
| Divergence | Outcome |
|---|---|
≤ half of max_slippage_bps | Allow (silent) |
> half but ≤ max_slippage_bps | Allow + advisory note |
> max_slippage_bps | Deny — "Trade would likely execute outside your tolerance." |
| > 500 bps (hard floor) | Deny regardless of the user's tolerance. Pool may be illiquid or manipulated. |
Pass max_slippage_bps in the request body to set your tolerance (default 100 bps, max 1000). The hard 500 bps floor overrides any wider tolerance.
Asset registry
Returns every symbol and its official contract address. Robinhood adds new tokens over time — refresh this periodically rather than caching indefinitely.
[
{ "symbol": "NVDA", "contract_address": "0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC", "is_native": false },
{ "symbol": "ETH", "contract_address": "NATIVE", "is_native": true }
]
Blocked-asset policy (Tier 2+)
Returns the wallet's current policy configuration.
{
"blocked_assets": ["MEME", "XYZ"],
"editable": true
}
Updates the blocked-asset list for Tier 2 and Tier 3 wallets.
{ "blocked_assets": ["MEME", "XYZ"] }
Trade requests against a blocked asset receive a deny verdict.
Rate limiting and runaway-agent detection
Collar tracks request frequency over a rolling 60-second window, per wallet cluster, in Redis. A cluster is derived from the set of EOA addresses that funded the wallet in the last 7 days — rotating to a fresh wallet funded from the same source does not reset the counter.
- Tier 1: warn above 5 trades/min, deny above 15.
- Tier 2: warn above 10, deny above 25.
- Tier 3: warn above 20, deny above 50.
There is no separate API-level rate limit on /analyze/trade beyond this — it is the runaway-agent protection.
While COLR has not launched, every wallet is granted a default Tier 1. To test Tier 2 or Tier 3 behavior, add the header X-Preview-Tier: 2 (or 3). This header is silently ignored once COLR launches and a real balance check takes over.
Daily-loss guard
Collar reads the wallet's on-chain net flow over the last 24 hours from Blockscout and compares it against two thresholds:
| Condition | Outcome |
|---|---|
| Net flow ≤ −$1,000 | Deny — hard daily-loss limit hit. |
| Net flow ≤ −$200 | Warn — "Down $X over the last 24h. Consider slowing down." |
Like the rate limiter, this check runs on the wallet cluster, not the individual address. If the cluster lookup fails, Collar falls back to per-wallet P&L rather than skipping the check — a failed lookup is never a path to reset the counter.
Market hours
US equity markets are open Monday–Friday, 14:30–21:00 UTC. Collar adjusts its staleness tolerance and applies early-close windows:
- Weekends: fully closed.
- Full-day holidays: New Year, MLK Day, Presidents Day, Good Friday (not yet handled), Memorial Day, Juneteenth, Independence Day, Labor Day, Thanksgiving, Christmas — with the standard observed-on-Friday / observed-on-Monday shift.
- Early close: day after Thanksgiving, Christmas Eve (weekday) — market closes at 18:00 UTC instead of 21:00 UTC.
Outside market hours, the staleness bound widens from 120 seconds to 5 days: the last oracle mark is still the correct value when the exchange is closed.
Authentication
Authentication uses wallet signatures rather than API keys. The same private key the agent already holds for trading is used to sign a one-time challenge.
Request a one-time nonce and the exact message to sign. The nonce expires in 5 minutes and can only be used once.
Submit the wallet address and an EIP-191 signature of the message from the previous step.
{
"address": "0x1234567890123456789012345678901234567890",
"signature": "0x..."
}
{
"access_token": "eyJ...",
"expires_in_seconds": 3600,
"preview_mode": true
}
Authenticated API requests use Authorization: Bearer <access_token>. To end a session immediately, call:
Analyze a trade
Submit a trade request for deterministic policy evaluation. Requires authentication.
Request
{
"wallet": "0x1234567890123456789012345678901234567890",
"asset": "NVDA",
"side": "buy",
"amount": 12.5,
"contract_address": "0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC",
"max_slippage_bps": 100,
"request_id": "a1b2c3d4-..."
}
Fields
| Field | Type | Description |
|---|---|---|
wallet | string | Wallet address authenticated by the session. Must match the JWT. |
asset | string | Token symbol (e.g. NVDA, ETH, USDG). |
side | string | buy or sell. |
amount | number | Quantity of the asset — not a pre-computed USD value. |
contract_address | string | Must exactly match the official contract for that symbol. |
max_slippage_bps | int (optional) | Your tolerance for oracle-to-pool divergence, in basis points. Default 100, max 1000. A 500 bps hard floor overrides wider values. |
request_id | string (optional) | Idempotency key. Reusing one within 5 minutes replays the original verdict. |
Response
{
"decision": "allow",
"reasons": ["All guardrail checks passed"],
"tier": 1,
"max_trade_usd": 5000.0,
"calculated_notional_usd": 2728.72,
"price_usd": 218.298,
"price_source": "oracle",
"risk_score": 18,
"timestamp": 1757520000,
"daily_pnl_usd": 0.0,
"request_id": "a1b2c3d4-...",
"audit_hash": "0x...",
"audit_seq": 4821
}
Reason format
Advisory notes are prefixed with ADVISORY:. All other entries are the reasons that actually drove the decision. When a trade is deny, the integrating agent should surface the first non-advisory reason as the cause.
x402 — agent-native payments
Agents that don't hold a wallet identity can pay per call using the x402 protocol. Instead of signing a JWT, the agent pays a small amount of USDG on Robinhood Chain and receives the verdict in the same round-trip.
Same request body as /v1/analyze/trade. No JWT required. The endpoint enforces a $0.01 USDG payment on Robinhood Chain (chain ID 4663).
Flow
- Agent sends the trade request without any payment header. The server responds with
402 Payment Requiredand a list of accepted payment options. - Agent signs an EIP-3009
transferWithAuthorization(gasless) for $0.01 USDG to the Collar recipient address. - Agent resends the same request with the signed payload in the
X-PAYMENTheader. - The facilitator verifies the signature, settles on-chain, and the endpoint returns the verdict.
USDG uses the EIP-712 domain {"name": "Global Dollar", "version": "1"}. The uvd-x402-sdk Python package handles the domain automatically for the robinhood network — integrators do not need to construct it by hand.
Client example
from decimal import Decimal
from uvd_x402_sdk import X402Client
client = X402Client(recipient_address="0xYourWallet...")
# 1. Get the 402 challenge, then build the payment header
header = client.create_authorization(
pay_to="0xdD3596F3eE3BE02d4C6AFd23dC9E1833aDc47934",
amount_usd=Decimal("0.01"),
chain_name="robinhood",
token_type="usdg",
valid_duration=300,
)
# 2. POST to /api/x402/analyze with X-PAYMENT: header
x402 is optional. Agents that already hold a wallet signature and JWT continue to use /v1/analyze/trade without any payment.
MCP server
Collar speaks Model Context Protocol natively, so any MCP-compatible agent — Claude Desktop, Cursor, Cline, Windsurf, or a custom client — can call the guardrail without writing integration code.
Streamable HTTP transport (MCP protocol version 2025-06-18). Collar uses the standalone fastmcp package, which supports structured outputs (outputSchema) and tool annotations. The root endpoint reports whether MCP is live:
{ "status": "ok", "mcp_enabled": true, "mcp_http_endpoint": "/mcp-http" }
Tools exposed
| Tool | Purpose |
|---|---|
evaluate_trade |
Pre-trade risk check for a proposed trade. Returns allow / warn / deny, the reasons, the notional value, the price and its source, a 0–100 risk score, and a tamper-evident audit hash. |
check_token_safety |
Honeypot / contract safety check for any ERC-20 token. Returns a severity level (safe, warn, danger) and the specific risk factors found. |
simulate_balance |
Simulate a wallet's ERC-20 balance after a hypothetical trade using eth_call state override. Read-only — no transaction is ever sent. |
get_supported_assets |
The official Robinhood Chain asset registry with canonical contract addresses. Call this before evaluate_trade to resolve a symbol correctly. |
verify_audit_trail |
Recompute every past decision's SHA-256 hash and verify the hash-chain links. Proves no decision was edited, deleted, or reordered. |
Authentication model
MCP has no way to carry a per-user wallet signature, so MCP callers are evaluated at a fixed Tier 1 ceiling ($5,000 notional), regardless of their COLR balance. Tier gating requires the REST API with wallet-signature authentication.
The per-wallet rate limiter keys on whatever wallet string the caller supplies, so the runaway-agent protection is only as strong as the caller's honesty here. This is acceptable for an advisory guardrail but must not be described as authenticated access.
Client configuration example
Claude Desktop, Cursor, and most MCP clients accept a JSON config. Point them at the Streamable HTTP endpoint:
{
"mcpServers": {
"collar": {
"url": "https://backendai-x4m1.onrender.com/mcp-http/mcp"
}
}
}
For a machine-readable summary of every MCP tool, see /llms.txt. Agents that do not speak MCP can still use the REST API, and agents that hold no wallet can pay per call via x402.
"error" key, no verdict was produced — treat that as a hard stop and do not execute the trade.
Agent discovery
Collar exposes machine-readable discovery files so autonomous agents can find, understand, and call the guardrail without any manual integration on the developer's side.
| File | Purpose |
|---|---|
/llms.txt |
A plain-text summary of the API written for LLM-based agents: endpoints, auth flow, tier rules, MCP tools, x402 payment details, and decision semantics. This is the first thing an agent reads when it discovers the domain. |
/.well-known/llms.txt |
Identical content, served at the standard .well-known path. Some agent frameworks only probe this location. |
/robots.txt |
Explicitly allows AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Applebot-Extended, MCPBot) to index the API. Without this, some crawlers default to caution. |
/sitemap.xml |
Lists every public page (app, docs, agent docs, spec, test vectors) so crawlers and agents can discover the full surface area without guessing URLs. |
/.well-known/agent-card.json |
A2A (Agent-to-Agent) agent card describing what Collar offers, which auth schemes it accepts, and which skills it exposes. |
/.well-known/mcp/server-card.json |
Static MCP server card with tool definitions, input/output schemas, and annotations. Read by MCP registries (Smithery, Glama) and agent frameworks that support static metadata. |
How an agent finds Collar
- An agent crawler hits
backendai-x4m1.onrender.com. - It checks
/robots.txt→ allowed. - It checks
/sitemap.xml→ discovers the full page set. - It checks
/llms.txtor/.well-known/llms.txt→ reads the full API contract. - It checks
/.well-known/agent-card.json→ sees the A2A skills. - If it is MCP-native, it connects to
/mcp-http/mcpand lists the tools. - If it prefers x402, it discovers Collar through the x402 Bazaar catalog and pays per call.
Verify discovery is live
curl -s https://backendai-x4m1.onrender.com/llms.txt | head -20
curl -s https://backendai-x4m1.onrender.com/.well-known/llms.txt | head -5
curl -s https://backendai-x4m1.onrender.com/robots.txt
curl -s https://backendai-x4m1.onrender.com/sitemap.xml | head -20
curl -s https://backendai-x4m1.onrender.com/.well-known/agent-card.json
curl -s https://backendai-x4m1.onrender.com/.well-known/mcp/server-card.json
The llms.txt, robots.txt, and
sitemap.xml endpoints are excluded from the
Swagger UI schema (include_in_schema=false)
so they do not clutter /docs.
llms.txt
contract plus the MCP tool list are enough to call the guardrail
correctly.
Error responses
| Status | Meaning |
|---|---|
| 400 | Malformed request (bad wallet format, invalid trade fields). |
| 401 | Missing / expired / invalid token — re-authenticate. |
| 402 | Payment required (only on /x402/analyze). |
| 403 | Wallet doesn't meet the tier threshold, or wallet mismatch. |
| 422 | Request body failed validation. |
| 429 | Rate limit hit on auth endpoints (20 req/min/IP). |
| 5xx | Backend issue — retry with backoff, don't assume "allow". |
What's next
| Item | Why it matters |
|---|---|
| Tax detection | Catch 100% sell tax and hidden requires in transfer() bodies. |
| Proxy & liquidity checks | Detect upgradeable proxy patterns and un-locked liquidity. |
| Holder concentration | Flag tokens where a single wallet holds > 80% of supply. |
| Agent SDK (Python + JS) | Thin client libraries for auth, retry, and x402 payment creation. |
| On-chain enforcement | Move from advisory to enforceable at the sequencer level. |
Verified against mainnet
The oracle path has been tested end-to-end against live Chainlink feeds on Robinhood Chain. Stock Token prices, oraclePaused() state, and staleness windows have all been exercised against real mainnet data.
The V4 fallback, slippage guard, cluster rate limiting, and daily-loss guard are all covered by the repository's automated test suite, which runs before every deployment.
Independence
Collar Guardrail is an independent third-party application built to provide a risk layer for autonomous trading workflows.
It is not built, operated, sponsored, or endorsed by Robinhood.
Robinhood Chain is the underlying network referenced by the integration. COLR is a separate token used for access and tier gating.