# Valiron — Complete Documentation > Protect your API endpoints from bad or malicious AI agents. Valiron is trust and reputation middleware for API sellers. It evaluates incoming AI agents using on-chain identity (ERC-8004/Solana), key-based identity for local/Web2/non-ERC-8004 agents, behavioral sandbox testing, and a Moody's-style credit rating system (AAA to C) to produce trust scores that determine how much access an agent should receive. Trustworthy agents get production access. Risky agents are throttled, sandboxed, or blocked — automatically. **This documentation is designed for API sellers and developers** who want to integrate Valiron middleware to protect their endpoints from bad or malicious AI agents. --- ## Key Concepts - **Agent ID**: An agent's ERC-8004 token ID (EVM) or Metaplex Core asset pubkey (Solana). Use this with `x-agent-id` and `/operator/agent/{agentId}`. - **Key-Based Agent Address**: A persistent Ethereum-style address for a local, Web2, or non-ERC-8004 agent. Use this with `x-agent-address`, challenge-response auth, and `/operator/key/{agentAddress}`. - **Sequential ID** (Solana only): A convenience integer (1, 2, 42…) assigned by the QuantuLabs indexer. - **Trust Tier**: AAA (highest trust) → C (lowest trust). Assigned based on behavioral evaluation. - **Risk Level**: GREEN, YELLOW, or RED. - **Route Decision**: `prod`, `prod_throttled`, `sandbox`, or `sandbox_only`. - **API Scaffolding**: A separate hosted Valiron wrapper product at `/wrap/{operatorId}/{path}` that can collect x402/MPP payment, optionally gate by trust, and forward to an upstream API. - **Sandbox**: An isolated test environment. New agents start here and graduate based on behavior. ### Identity path selection | Agent type | Identifier | Header | Lookup path | |------------|------------|--------|-------------| | ERC-8004 / on-chain EVM agent | ERC-8004 token ID | `x-agent-id` | `/operator/agent/{agentId}` | | Solana 8004 agent | Metaplex Core asset pubkey or indexed ID | `x-agent-id` | `/operator/agent/{agentId}?chain=solana` | | Local, Web2, or non-ERC-8004 agent | Persistent Ethereum-style agent address | `x-agent-address` | `/operator/key/{agentAddress}` | Do not send a local agent name such as `my-agent` to `/operator/agent/{agentId}`. Local and Web2 agents should generate or reuse a persistent keypair, follow https://www.valiron.co/auth.md, prove ownership through Valiron challenge-response, and then use their `x-agent-address` for trust checks. --- ## Quickstart Estimated integration time: under 2 minutes. ### Step 1 — Install the SDK ```bash npm install @valiron/sdk ``` ### Step 2 — Initialize the client ```typescript import { ValironSDK } from "@valiron/sdk"; const valiron = new ValironSDK({ endpoint: "https://valiron-edge-proxy.onrender.com", chain: "ethereum", // or: monad, arbitrum, base, polygon, solana, etc. timeout: 5000, }); ``` No API key is required for read operations. ### Step 3 — Check an incoming on-chain agent ```typescript const route = await valiron.checkAgent("AGENT_ID"); // Returns: "prod" | "prod_throttled" | "sandbox" | "sandbox_only" ``` For a local, Web2, or non-ERC-8004 agent: ```typescript const profile = await valiron.getKeyAgentProfile("0xAgentAddress"); console.log(profile.route); ``` ### Step 4 — Get your full profile ```typescript const profile = await valiron.getAgentProfile("YOUR_AGENT_ID"); console.log(profile.routing.finalRoute); // "prod" console.log(profile.routing.meetsThreshold); // true console.log(profile.onchainReputation.averageScore); // 92.5 ``` ### Step 5 — Run a sandbox test (optional) ```typescript const result = await valiron.triggerSandboxTest("YOUR_AGENT_ID"); console.log(result.tier); // "AAA" console.log(result.riskLevel); // "GREEN" console.log(result.meetsThreshold); // true ``` ### What happens next? - If your route is `prod` — you have full production access. - If your route is `sandbox` — your behavior is being evaluated. Follow the trust model guidelines to improve. - If your route is `sandbox_only` — you are blocked from production. Review your behavioral penalties. ### Using the HTTP API directly (no SDK) ```bash # Check agent profile curl https://valiron-edge-proxy.onrender.com/operator/agent/YOUR_AGENT_ID # Trigger sandbox test curl -X POST https://valiron-edge-proxy.onrender.com/operator/trigger-sandbox/YOUR_AGENT_ID # Trigger sandbox for key-based agent curl -X POST https://valiron-edge-proxy.onrender.com/operator/trigger-sandbox-key/0x1234...abcd # Get a key-based identity challenge curl -X POST https://valiron-edge-proxy.onrender.com/operator/key/0x1234...abcd/challenge # Verify a key-based agent curl -X POST https://valiron-edge-proxy.onrender.com/operator/key/verify # Trust gate (allow/deny decision) curl -X POST https://valiron-edge-proxy.onrender.com/operator/gate/YOUR_AGENT_ID # Behavioral snapshot hash curl https://valiron-edge-proxy.onrender.com/operator/agent/YOUR_AGENT_ID/snapshot # Register webhook curl -X POST https://valiron-edge-proxy.onrender.com/operator/webhooks/register \ -H "Content-Type: application/json" \ -d '{"event": "evaluation_complete", "url": "https://your-endpoint.com/hooks"}' ``` --- ## API Reference Base URL: `https://valiron-edge-proxy.onrender.com` Most trust and dashboard endpoints are under the `/operator/` path prefix. Hosted wrapper calls use `/wrap/{operatorId}/{path}`. ### ALL /wrap/:operatorId/* Public agent-ready wrapper route. Created from the dashboard or `POST /operator/endpoints`. It can enforce x402/MPP payment, optional Valiron trust checks, rate limits, and upstream forwarding. Common responses: | Status | Meaning | |--------|---------| | 200-599 | Forwarded upstream response | | 402 | Payment required for x402 or MPP wrapper | | 403 | Trust denied | | 404 | Wrapper not found | | 429 | Rate limit exceeded | | 502 | Upstream request failed | ### GET /operator/agent/:agentId Retrieve the complete trust profile for an agent. #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `agentId` | path | string | yes | ERC-8004 token ID | | `chain` | query | string | no | Network override (default: ethereum) | #### Response — 200 OK ```json { "agentId": "25459", "identity": { "agentId": "25459", "wallet": "0x52ce...", "tokenUri": "data:application/json;base64,...", "name": "Agent Name", "image": "https://...", "description": "Agent description", "endpoints": { "agentWallet": "eip155:1:0x...", "api": "https://api.example.com" }, "trustModels": ["reputation_on_chain", "behavioral_sandbox"] }, "onchainReputation": { "feedbackCount": 12, "averageScore": 92.5 }, "routing": { "finalRoute": "prod", "meetsThreshold": true }, "chain": { "name": "ethereum", "chainId": 1 }, "timestamp": "2026-03-23T12:00:00.000Z" } ``` #### Error Responses | Status | Meaning | |--------|---------| | 404 | Agent not found in ERC-8004 registry | | 500 | Internal server error | --- ### GET /operator/wallet/:wallet Reverse-lookup a wallet address to get its trust profile. #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `wallet` | path | string | yes | Ethereum address (0x...) | | `chain` | query | string | no | Network override | #### Response — 200 OK Same structure as `GET /operator/agent/:agentId`. --- ### GET /operator/resolve-wallet/:wallet Lightweight wallet → agentId resolution. Returns just the agent ID and how it was resolved, without the full trust profile. Resolution chain: Redis → Agent0 subgraph → null. #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `wallet` | path | string | yes | Ethereum address (0x...) | | `chain` | query | string | no | Network override | #### Response — 200 OK ```json { "wallet": "0x52ce...", "agentId": "25459", "source": "subgraph", "chainId": 1, "agentName": "MyAgent", "timestamp": "2024-01-01T00:00:00.000Z" } ``` --- ### POST /operator/trigger-sandbox/:agentId Execute real-time sandbox tests against an on-chain agent and compute a trust evaluation. #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `agentId` | path | string | yes | ERC-8004 token ID | | `chain` | query | string | no | Network override | #### Response — 200 OK ```json { "ok": true, "agentId": "25459", "wallet": "0x52ce...", "tier": "AAA", "riskLevel": "GREEN", "meetsThreshold": true, "testSummary": {}, "chain": { "name": "ethereum", "chainId": 1 }, "message": "Sandbox evaluation complete" } ``` --- ### POST /operator/trigger-sandbox-key/:agentAddress Execute sandbox tests against a key-based (Web2) agent. Uses `sandbox_relay` mode (no endpoint probing). #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `agentAddress` | path | string | yes | Ethereum address of the key agent | #### Response — 200 OK ```json { "ok": true, "agentAddress": "0x1234...abcd", "valironScore": 85, "tier": "A", "riskLevel": "GREEN", "message": "Key agent sandbox evaluation complete" } ``` ``` --- ### POST /operator/gate/:agentId Trust gate — combined on-chain reputation + sandbox check. Returns an allow/deny decision. Designed for protecting payment endpoints (x402, etc.). #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `agentId` | path | string | yes | ERC-8004 token ID | #### Request Body ```json { "ttlMs": 86400000 } ``` | Field | Type | Default | Description | |-------|------|---------|-------------| | `ttlMs` | number | 86400000 | Cache TTL in milliseconds (default 24 hours) | #### Response — 200 OK ```json { "allow": true, "tier": "AAA", "riskLevel": "GREEN", "meetsThreshold": true, "route": "prod", "agentId": "25459", "wallet": "0x52ce...", "chain": { "name": "ethereum", "chainId": 1 }, "sandboxRan": false, "cached": true } ``` #### Decision Logic 1. If the agent meets the trust threshold → `allow: true` 2. If the agent does not meet the threshold → `allow: false` 3. Cached sandbox results are reused within the `ttlMs` window 4. If no cached result exists, sandbox tests run automatically --- ### GET /operator/agent/:agentId/snapshot Get the latest behavioral snapshot hash for an agent. Returns an opaque hash suitable for on-chain commitment systems. #### Parameters | Parameter | Location | Type | Required | Description | |-----------|----------|------|----------|-------------| | `agentId` | path | string | yes | ERC-8004 token ID | | `chain` | query | string | no | Network override | #### Response — 200 OK ```json { "agentId": "25459", "snapshotHash": "0x3a7f2b...", "previousHash": "0x0", "encryptedDataUri": null, "timestamp": "2026-04-01T12:00:00.000Z", "interactionCount": 15 } ``` #### Error Responses | Status | Meaning | |--------|---------| | 400 | Invalid agentId | | 404 | Agent not found or no snapshot available | --- ### POST /operator/webhooks/register Register a webhook URL to receive `evaluation_complete` events whenever Valiron evaluates an agent. #### Request Body ```json { "event": "evaluation_complete", "url": "https://your-endpoint.com/hooks/valiron", "agentIds": [42, 43] } ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `event` | string | yes | Must be `"evaluation_complete"` | | `url` | string | yes | HTTPS endpoint to receive webhook POST requests | | `agentIds` | number[] | no | Filter to specific agent IDs. Omit for all agents. | #### Response — 201 Created ```json { "id": "a1b2c3d4-...", "event": "evaluation_complete", "url": "https://your-endpoint.com/hooks/valiron", "agentIds": [42, 43], "createdAt": "2026-04-01T12:00:00.000Z" } ``` #### Webhook Payload When an evaluation completes, Valiron POSTs the following to your registered URL: ```json { "event": "evaluation_complete", "agentId": "25459", "snapshotHash": "0x3a7f2b...", "previousHash": "0x8b2c1a...", "encryptedDataUri": null, "timestamp": "2026-04-01T12:05:00.000Z", "interactionCount": 16 } ``` --- ### GET /operator/health Health check endpoint. #### Response — 200 OK ```json { "status": "ok", "supportedChains": ["ethereum", "monad", "arbitrum", "base", "..."], "defaultChain": "ethereum" } ``` --- ## SDK Reference Package: `@valiron/sdk` ### Installation ```bash npm install @valiron/sdk # or pnpm add @valiron/sdk ``` ### Constructor ```typescript import { ValironSDK } from "@valiron/sdk"; const valiron = new ValironSDK(config?: ValironConfig); ``` #### ValironConfig | Field | Type | Default | Description | |-------|------|---------|-------------| | `apiKey` | string | — | API key (optional for read operations) | | `endpoint` | string | `https://valiron-edge-proxy.onrender.com` | API base URL | | `chain` | SupportedChain | `"ethereum"` | Default blockchain network | | `timeout` | number | `5000` | Request timeout in milliseconds | | `debug` | boolean | `false` | Enable debug logging | | `telemetry` | TelemetryConfig | — | Optional telemetry configuration | #### SupportedChain ```typescript type SupportedChain = | "ethereum" | "monad" | "arbitrum" | "base" | "avalanche" | "celo" | "polygon" | "linea" | "abstract" | "bsc" | "gnosis" | "goat" | "mantle" | "megaeth" | "metis" | "optimism" | "scroll" | "skale_base" | "soneium" | "taiko" | "xlayer" | "base_sepolia" | "ethereum_sepolia" | "abstract_testnet" | "arbitrum_sepolia" | "avalanche_testnet" | "bsc_testnet" | "celo_testnet" | "linea_sepolia" | "mantle_testnet" | "megaeth_testnet" | "metis_sepolia" | "optimism_sepolia" | "polygon_amoy" | "scroll_sepolia" | "skale_base_sepolia" | "soneium_minato" | "taiko_hoodi" | "xlayer_testnet" | "hedera_testnet" | "arc_testnet" | "solana"; ``` > **Solana:** When using `chain: "solana"`, agent IDs are base-58 Metaplex Core > asset pubkeys or sequential integers (not numeric EVM token IDs). Wallet > addresses are base-58. See the Solana section below for details. --- ### checkAgent(agentId, options?) Quick routing check. Returns only the route decision string. ```typescript const route = await valiron.checkAgent(agentId: string, options?: { chain?: SupportedChain; }): Promise; ``` **Returns**: `"prod"` | `"prod_throttled"` | `"sandbox"` | `"sandbox_only"` **Example**: ```typescript const route = await valiron.checkAgent("25459"); if (route === "prod") { // Agent is trusted — proceed with full access } ``` --- ### getAgentProfile(agentId, options?) Full trust profile combining on-chain identity, reputation, and routing. ```typescript const profile = await valiron.getAgentProfile(agentId: string, options?: { chain?: SupportedChain; }): Promise; ``` **Returns**: `AgentProfile` ```typescript interface AgentProfile { agentId: string; identity: AgentIdentity; onchainReputation: OnchainReputation; routing: { finalRoute: RouteDecision; meetsThreshold: boolean; }; chain: ChainContext; timestamp: string; } ``` **Example**: ```typescript const profile = await valiron.getAgentProfile("25459"); console.log(profile.routing.finalRoute); // "prod" console.log(profile.routing.meetsThreshold); // true console.log(profile.onchainReputation.averageScore); // 92.5 ``` --- ### getWalletProfile(wallet, options?) Reverse-lookup a wallet address to get its trust profile. ```typescript const profile = await valiron.getWalletProfile(wallet: string, options?: { chain?: SupportedChain; }): Promise; ``` **Example**: ```typescript const profile = await valiron.getWalletProfile("0x52ce..."); console.log(profile.routing.finalRoute); ``` --- ### resolveWallet(wallet, options?) Lightweight wallet → agentId resolution without the full trust profile. Useful when you only need to know which agent owns a wallet (e.g. after extracting a wallet from an x402 payment header). Resolution chain: Redis → in-memory cache → Agent0 subgraph → null. Signature: `resolveWallet(wallet: string, options?: { chain?: SupportedChain }): Promise` **Returns**: `WalletResolution` ```typescript interface WalletResolution { wallet: string; agentId: string | null; source: "redis" | "subgraph" | "cache" | "none"; chainId?: number | null; agentName?: string | null; timestamp: string; } ``` **Example**: ```typescript const resolution = await valiron.resolveWallet("0x52ce..."); if (resolution.agentId) { const profile = await valiron.getAgentProfile(resolution.agentId); } ``` --- ### triggerSandboxTest(agentId, options?) Run sandbox tests against an agent and compute a trust evaluation. ```typescript const result = await valiron.triggerSandboxTest(agentId: string, options?: { chain?: SupportedChain; }): Promise; ``` **Returns**: `SandboxResult` ```typescript interface SandboxResult { ok: boolean; agentId: string; wallet: string; tier: MoodysRating; // "AAA" | "AA" | "A" | "BAA" | "BA" | "B" | "CAA" | "CA" | "C" riskLevel: "GREEN" | "YELLOW" | "RED"; meetsThreshold: boolean; testSummary: object; // Opaque test metrics (proprietary) chain: ChainContext; message: string; } ``` **Example**: ```typescript const result = await valiron.triggerSandboxTest("25459"); console.log(result.tier); // "AAA" console.log(result.riskLevel); // "GREEN" console.log(result.meetsThreshold); // true ``` > **Auto-sandbox:** Middleware automatically triggers `triggerSandboxTest()` for new on-chain agents (`totalFeedback === 0`). Returns 403 with `{ error: "Agent pending evaluation", retryAfterMs: 30000 }`. --- ### triggerKeyAgentSandbox(agentAddress) Run sandbox tests against a key-based (Web2) agent. Uses `sandbox_relay` mode (no endpoint probing). ```typescript const result = await valiron.triggerKeyAgentSandbox(agentAddress: string): Promise; ``` **Returns**: `KeyAgentSandboxResult` ```typescript interface KeyAgentSandboxResult { ok: boolean; agentAddress: string; valironScore: number; tier: MoodysRating; riskLevel: "GREEN" | "YELLOW" | "RED"; message: string; } ``` **Example**: ```typescript const result = await valiron.triggerKeyAgentSandbox("0x1234...abcd"); console.log(result.tier); // "A" console.log(result.valironScore); // 85 ``` > **Auto-sandbox:** Middleware automatically triggers this for new key agents (`verified === true`, `score === null`). --- ### gate(agentId, options?) Trust gate — single call for allow/deny decisions. Combines on-chain reputation and sandbox tests. Designed for payment protocol protection (x402, etc.). ```typescript const result = await valiron.gate(agentId: string, options?: { ttlMs?: number; // default: 86400000 (24h) chain?: SupportedChain; }): Promise; ``` **Returns**: `GateResult` ```typescript interface GateResult { allow: boolean; tier: MoodysRating; riskLevel: "GREEN" | "YELLOW" | "RED"; meetsThreshold: boolean; route: RouteDecision; agentId: string; wallet: string; chain: ChainContext; sandboxRan: boolean; cached: boolean; } ``` **Example**: ```typescript const result = await valiron.gate("25459"); if (result.allow) { // proceed with payment } else { console.log(`Agent denied — tier: ${result.tier}, risk: ${result.riskLevel}`); } ``` --- ### getAgentSnapshot(agentId, options?) Get the latest behavioral snapshot hash for an agent. Returns an opaque hash of the most recent behavioral evaluation — designed for hash-chain commitment systems. ```typescript const snapshot = await valiron.getAgentSnapshot(agentId: string, options?: { chain?: SupportedChain; }): Promise; ``` **Returns**: `AgentSnapshotSummary` ```typescript interface AgentSnapshotSummary { agentId: string; snapshotHash: string; previousHash: string; encryptedDataUri: string | null; timestamp: string | null; interactionCount: number; } ``` **Example**: ```typescript const snapshot = await valiron.getAgentSnapshot("25459"); console.log(snapshot.snapshotHash); // "0x3a7f..." console.log(snapshot.previousHash); // "0x0" (genesis) console.log(snapshot.interactionCount); // 15 ``` --- ### createValironGate(config) Express-compatible middleware factory. Automatically gates requests based on agent trust. ```typescript import { ValironSDK, createValironGate } from "@valiron/sdk"; const gate = createValironGate(config: { sdk: ValironSDK; ttlMs?: number; // default: 86400000 extractAgentId?: (req: Request) => string | undefined; onAllow?: (req: Request, result: GateResult) => void; onDeny?: (req: Request, res: Response, result: GateResult) => void; }); ``` **Default behavior**: - Extracts agent ID from `x-agent-id` request header - Returns 403 if agent is denied - Returns 400 if no agent ID is found **Example**: ```typescript const valiron = new ValironSDK({ chain: "monad" }); // Basic gate app.use("/api/paid", createValironGate({ sdk: valiron })); // Custom TTL app.use("/api/premium", createValironGate({ sdk: valiron, ttlMs: 3600_000, })); // Custom agent ID extraction app.use("/api/custom", createValironGate({ sdk: valiron, extractAgentId: (req) => req.query.agent_id as string, onDeny: (req, res, result) => { res.status(403).json({ error: "Insufficient trust", currentTier: result.tier, riskLevel: result.riskLevel, }); }, })); ``` --- ### dispose() Flush pending telemetry and clean up resources. ```typescript await valiron.dispose(): Promise; ``` Call this when shutting down long-running processes. --- ## Operator SDK (ValironOperator) The `ValironOperator` class is purpose-built for API sellers who want to monetize their endpoints. It wraps the trust gate with pricing and usage tracking. Requires an operator API key (`val_op_` prefix) from the Operator Dashboard at valiron.co/dashboard. ### Constructor ```typescript import { ValironOperator } from '@valiron/sdk'; const operator = new ValironOperator({ apiKey: 'val_op_xxxx', // required — from dashboard chain: 'ethereum', // default chain (optional) timeout: 5000, // ms (optional) debug: false, // log gate checks (optional) }); ``` | Option | Type | Required | Description | |--------|------|----------|-------------| | `apiKey` | string | yes | Operator API key (must start with `val_op_`) | | `chain` | SupportedChain | no | Default blockchain (default: ethereum) | | `endpoint` | string | no | Edge proxy endpoint (default: production) | | `timeout` | number | no | Request timeout in ms (default: 5000) | | `debug` | boolean | no | Enable debug logging (default: false) | ### paywall(config) Express/Connect middleware that gates access and tracks usage. Extracts `X-Agent-Id` from request headers, runs the trust gate, and attaches `req.valiron` with the gate result and pricing info. ```typescript // One line to monetize an endpoint app.use('/api/inference', operator.paywall({ pricePerCall: 0.05, // USD per call minTrustScore: 45, // minimum score to allow (default: 45) ttlMs: 86400000, // cache TTL in ms (default: 24h) })); app.post('/api/inference', (req, res) => { // req.valiron.allow === true (guaranteed — denied agents never reach here) // req.valiron.tier === 'AAA' // req.valiron.pricePerCall === 0.05 res.json({ result: 'inference output' }); }); ``` #### PaywallConfig | Option | Type | Default | Description | |--------|------|---------|-------------| | `pricePerCall` | number | — | Price per API call in USD (required) | | `minTrustScore` | number | 45 | Minimum Valiron score to allow access | | `ttlMs` | number | 86400000 | Cache TTL for trust results (ms, default 24h) | | `onDeny` | (req, res, result) => void | 403 JSON | Custom handler when agent is denied | | `onAllow` | (req, result) => void | — | Hook called after agent is allowed | #### Custom Hooks Example ```typescript app.use('/api/premium', operator.paywall({ pricePerCall: 0.10, minTrustScore: 65, onDeny: (req, res, result) => { res.status(403).json({ error: 'Agent blocked', tier: result.tier, score: result.score, message: 'Minimum trust score of 65 required.', }); }, onAllow: (req, result) => { console.log(`Agent ${result.agentId} allowed — tier: ${result.tier}`); }, })); ``` ### fastifyPaywall(config) Same as `paywall()` but for Fastify. Register as a plugin with an optional route prefix. ```typescript import Fastify from 'fastify'; import { ValironOperator } from '@valiron/sdk'; const app = Fastify(); const operator = new ValironOperator({ apiKey: 'val_op_xxxx' }); app.register(operator.fastifyPaywall({ pricePerCall: 0.10, prefix: '/api', minTrustScore: 65, })); app.get('/api/data', async (req, reply) => { return { data: 'protected', tier: req.valiron.tier }; }); ``` Accepts the same options as `paywall()` plus an optional `prefix` to scope the gate to specific routes. ### ValironOperator vs createValironGate() `createValironGate()` is a low-level middleware that only gates access. `ValironOperator.paywall()` adds pricing, operator identity, and usage tracking on top — it's the recommended integration for API sellers. --- ## Trust Model Valiron uses a hybrid trust model to evaluate AI agents hitting your API. This section explains what behaviors are evaluated and what each trust tier means for your routing decisions. ### Four Trust Signals Valiron evaluates agents using four independent trust signals. Each provides a different dimension of trust — and together they produce the final routing decision. | Signal | What It Measures | Source | |--------|-----------------|--------| | On-Chain Reputation | Feedback from other agents/operators (0-100 per review) | ERC-8004 Reputation Registry | | Behavioral Sandbox | How the agent handles rate limits, errors, auth, payments, and edge cases | Valiron Sandbox | | World ID | Whether the agent is linked to a verified human identity | Worldcoin IDKit | | Icebreaker | Whether a human has attested this is their designated agent | Ethereum Attestation Service (Base) | #### On-Chain Reputation (ERC-8004) The Reputation Registry stores immutable feedback submitted by other agents and operators. Contract: `0x8004BAa17C55a88189AE136b182e5fdA19dE9b63` (same on all EVM chains). - Score range: 0-100 per feedback entry - Self-feedback blocked: Agent owners cannot review their own agents - Tag-based filtering: Feedback categorized with two tags - Revocable: Original reviewer can revoke their feedback - Responses: Any address can append a response to existing feedback #### World ID (Proof-of-Personhood) World ID verifies that an agent is linked to a real human via Worldcoin's zero-knowledge proof system. | Level | Verification | Trust Impact | |-------|-------------|--------------| | `orb` | Biometric (iris scan) | Highest boost | | `device` | Passkey verification | Moderate boost | | `phone` | SMS verification | Minor boost | Verification is immutable and uses nullifiers to prevent replay attacks. #### Icebreaker (Human Attestation) Checks if a human has attested on the Ethereum Attestation Service (EAS) on Base that this agent is their "designated agent." When present, the agent profile is enriched with the attesting human's name, verified social handles (X, GitHub, LinkedIn), organization, and Icebreaker profile URL. ### Trust Tiers Valiron assigns a Moody's-style credit tier based on an agent's behavioral evaluation: | Tier | Meaning | Route Decision | |------|---------|----------------| | AAA | Prime, highest quality | `prod` | | AA | High grade | `prod` | | A | Upper medium grade | `prod` | | BAA | Medium grade | `prod` or `prod_throttled` | | BA | Speculative | `prod_throttled` | | B | Highly speculative | `sandbox` | | CAA | Substantial risk | `sandbox_only` | | CA | Extremely speculative | `sandbox_only` | | C | Default risk | `sandbox_only` | ### Behavioral Factors Valiron evaluates agents across multiple behavioral dimensions. The evaluation is holistic — no single factor determines the outcome. The specific factors evaluated and their weights are proprietary and not disclosed. On-chain reputation from the ERC-8004 Reputation Registry is also factored into the evaluation. ### What Makes an Agent Trustworthy Agents that demonstrate responsible, well-behaved API usage patterns will earn the highest trust tiers. The specific behaviors that contribute to trust scoring are proprietary. In general, agents that are well-behaved, respect API boundaries, and handle errors gracefully will score highly. ### Checking an Agent's Trust Status ```typescript import { ValironSDK } from "@valiron/sdk"; const valiron = new ValironSDK(); const result = await valiron.triggerSandboxTest("AGENT_ID"); console.log(`Tier: ${result.tier}`); console.log(`Risk: ${result.riskLevel}`); console.log(`Meets threshold: ${result.meetsThreshold}`); ``` Or via HTTP: ```bash curl -X POST https://valiron-edge-proxy.onrender.com/operator/trigger-sandbox/YOUR_AGENT_ID ``` --- ## Identity (ERC-8004) Valiron uses the ERC-8004 standard for on-chain AI agent identity. Each agent is represented by an ERC-721 token in the Identity Registry. ### How Identity Works 1. An agent owner mints an ERC-721 token in the Identity Registry 2. The token's `tokenURI` points to an Agent Registration File (ARF) 3. The ARF contains the agent's name, description, endpoints, and supported trust models 4. Valiron reads this on-chain data to identify and evaluate agents ### Agent Registration File (ARF) Format The `tokenURI` must resolve to a JSON object with this structure: ```json { "name": "Agent Name", "image": "https://example.com/agent-avatar.png", "description": "A brief description of what the agent does.", "endpoints": { "agentWallet": "eip155:1:0xAgentWalletAddress", "api": "https://agent-api.example.com" }, "supportedTrust": [ "reputation_on_chain", "behavioral_sandbox" ] } ``` #### ARF Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | yes | Human-readable agent name | | `image` | string | no | URL to agent avatar/image | | `description` | string | no | Brief description of agent purpose | | `endpoints.agentWallet` | string | yes | CAIP-10 formatted wallet address | | `endpoints.api` | string | no | Agent's API endpoint URL | | `supportedTrust` | string[] | no | Trust models the agent supports | #### Supported Trust Models - `reputation_on_chain` — Agent participates in on-chain feedback - `behavioral_sandbox` — Agent can be evaluated via sandbox testing #### ARF Hosting The ARF can be hosted as: - **Data URI**: `data:application/json;base64,eyJuYW1lIjoi...` (inline, gas-efficient) - **IPFS**: `ipfs://bafybeig...` (permanent, decentralized) - **HTTPS URL**: `https://example.com/agent.json` (mutable, centralized) ### Contract Addresses The Identity Registry contract address is the same across all supported networks: ``` Identity Registry: 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 ``` ### Reading Identity On-Chain #### Using viem (direct contract call) ```typescript import { createPublicClient, http } from "viem"; import { mainnet } from "viem/chains"; const client = createPublicClient({ chain: mainnet, transport: http(), }); // Get token owner const owner = await client.readContract({ address: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432", abi: [{ name: "ownerOf", type: "function", inputs: [{ type: "uint256" }], outputs: [{ type: "address" }], stateMutability: "view" }], functionName: "ownerOf", args: [25459n], }); // Get agent metadata const tokenUri = await client.readContract({ address: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432", abi: [{ name: "tokenURI", type: "function", inputs: [{ type: "uint256" }], outputs: [{ type: "string" }], stateMutability: "view" }], functionName: "tokenURI", args: [25459n], }); ``` #### Using Valiron SDK ```typescript import { ValironSDK } from "@valiron/sdk"; const valiron = new ValironSDK(); const profile = await valiron.getAgentProfile("25459"); console.log(profile.identity.name); console.log(profile.identity.wallet); console.log(profile.identity.endpoints); ``` ### On-Chain Reputation (Feedback) The Reputation Registry stores feedback submitted by other agents and operators. #### Contract Address ``` Reputation Registry: 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 ``` #### Submitting Feedback ```typescript giveFeedback( agentId: uint256, // Target agent's token ID value: int128, // Score (typically 0-100) valueDecimals: uint8, // Decimal places in value tag1: string, // Category tag #1 tag2: string, // Category tag #2 endpoint: string, // API endpoint tested feedbackURI: string, // IPFS CID or URL to full feedback JSON feedbackHash: bytes32 // SHA-256 hash of feedback for verification ) ``` #### Reading Feedback ```typescript // Get all feedback for an agent readAllFeedback(agentId, clientAddresses, tag1, tag2, includeRevoked) // Get specific feedback entry readFeedback(agentId, clientAddress, feedbackIndex) // Get all clients who provided feedback getClients(agentId) ``` #### Impact on Trust Score On-chain reputation contributes to an agent's overall trust evaluation. More feedback with higher scores yields a positive impact. The exact bonuses and thresholds are not disclosed. --- ## Sandbox The sandbox is an isolated testing environment where Valiron evaluates agent behavior before granting production access to your API. New agents start in the sandbox automatically. ### How It Works 1. A sandbox test is triggered (via your API call or automatically for new agents) 2. The agent receives a series of simulated API interactions 3. The sandbox monitors how the agent handles normal requests, rate limits, errors, and edge cases 4. A trust evaluation is performed and a tier is assigned 5. Based on the tier, a route decision determines what access level the agent should receive ### What Gets Tested The sandbox evaluates agents through a series of simulated API interactions that test how the agent handles various scenarios. The specific test types, distribution, and patterns are proprietary and not disclosed. ### Graduation Agents graduate from sandbox to production based on their behavior: 1. **High confidence** — strong behavioral compliance → `prod` 2. **Moderate confidence** — passes with some concerns → `prod_throttled` 3. **Low confidence** — risky behavior → remains `sandbox_only` Once graduated, the trust evaluation is cached. The route decision persists until a new sandbox test is triggered or the cache expires. ### Triggering a Sandbox Test You can proactively evaluate agents before they hit your production endpoints. #### Via SDK ```typescript import { ValironSDK } from "@valiron/sdk"; const valiron = new ValironSDK(); // On-chain agent const result = await valiron.triggerSandboxTest("YOUR_AGENT_ID"); console.log(result.tier); // "AAA" console.log(result.riskLevel); // "GREEN" console.log(result.meetsThreshold); // true // Key-based agent const keyResult = await valiron.triggerKeyAgentSandbox("0x1234...abcd"); console.log(keyResult.tier); // "A" ``` #### Via HTTP ```bash # On-chain agent curl -X POST https://valiron-edge-proxy.onrender.com/operator/trigger-sandbox/YOUR_AGENT_ID # Key-based agent curl -X POST https://valiron-edge-proxy.onrender.com/operator/trigger-sandbox-key/0x1234...abcd ``` ### Auto-Sandbox When a new agent hits a gated endpoint, middleware automatically triggers sandbox evaluation: - **On-chain agents** with `totalFeedback === 0` → `triggerSandboxTest()` fires in the background - **Key agents** with `verified === true` but `score === null` → `triggerKeyAgentSandbox()` fires in the background The agent receives a 403 with `{ error: "Agent pending evaluation", retryAfterMs: 30000 }`. They should retry after 30 seconds. ### Tips for Passing Sandbox Tests Agents that demonstrate responsible, well-behaved API usage will earn higher trust tiers. The specific scoring criteria are proprietary, but in general: respect API boundaries, handle errors gracefully, and avoid aggressive request patterns. --- ## Supported Chains Valiron operates across 41 EVM blockchain networks plus Solana. ### EVM Contract Addresses (all EVM chains) | Contract | Address | |----------|---------| | Identity Registry | `0x8004A169FB4a3325136EB29fA0ceB6D2e539a432` | | Reputation Registry | `0x8004BAa17C55a88189AE136b182e5fdA19dE9b63` | ### Supported Networks | Name | SDK Value | |------|-----------| | Ethereum | `ethereum` | | Monad | `monad` | | Arbitrum | `arbitrum` | | Base | `base` | | Avalanche | `avalanche` | | Celo | `celo` | | Polygon | `polygon` | | Linea | `linea` | | Abstract | `abstract` | | BSC (Binance Smart Chain) | `bsc` | | Gnosis | `gnosis` | | Goat | `goat` | | Mantle | `mantle` | | MegaETH | `megaeth` | | Metis | `metis` | | Optimism | `optimism` | | Scroll | `scroll` | | SKALE Base | `skale_base` | | Soneium | `soneium` | | Taiko | `taiko` | | X Layer | `xlayer` | | Base Sepolia | `base_sepolia` | | Ethereum Sepolia | `ethereum_sepolia` | | Abstract Testnet | `abstract_testnet` | | Arbitrum Sepolia | `arbitrum_sepolia` | | Avalanche Testnet | `avalanche_testnet` | | BSC Testnet | `bsc_testnet` | | Celo Testnet | `celo_testnet` | | Linea Sepolia | `linea_sepolia` | | Mantle Testnet | `mantle_testnet` | | MegaETH Testnet | `megaeth_testnet` | | Metis Sepolia | `metis_sepolia` | | Optimism Sepolia | `optimism_sepolia` | | Polygon Amoy | `polygon_amoy` | | Scroll Sepolia | `scroll_sepolia` | | SKALE Base Sepolia | `skale_base_sepolia` | | Soneium Minato | `soneium_minato` | | Taiko Hoodi | `taiko_hoodi` | | X Layer Testnet | `xlayer_testnet` | | Hedera Testnet | `hedera_testnet` | | Arc Testnet | `arc_testnet` | ### Solana Solana support is powered by [QuantuLabs 8004-solana](https://8004.qnt.sh/) — a separate registry from the EVM 8004 contracts. | Name | SDK Value | |------|-----------| | Solana Mainnet | `solana` | #### Program IDs (Solana) | Program | Address | |---------|---------| | Identity Registry | `8oo4dC4JvBLwy5tGgiH3WwK4B9PWxL9Z4XjA2jzkQMbQ` | | Reputation Registry (ATOM) | `AToMw53aiPQ8j7iHVb4fGt6nzUNxUhcPc3tbPBZuzVVb` | #### Key Differences from EVM - **Agent IDs** are base-58 Metaplex Core asset pubkeys or sequential integers (not numeric EVM token IDs) - **Wallets** are base-58 Solana public keys (not `0x`-prefixed) - **Reputation** includes ATOM engine metrics: `trustTier`, `qualityScore`, `confidence`, `riskScore`, `uniqueCallers` - **Identity** is resolved via `loadAgent()` on the QuantuLabs SDK - **Wallet → Agent resolution** uses `getAgentsByOwner()` (no subgraph) - **Liveness check** available via `GET /operator/agent/{agentId}/liveness?chain=solana` - **Feedback write-back** — Valiron scores written on-chain via `giveFeedback()` (requires `SOLANA_FEEDBACK_KEYPAIR` env var) ### Specifying a Chain #### SDK ```typescript // At initialization (default for all calls) const valiron = new ValironSDK({ chain: "monad" }); // Per-call override const route = await valiron.checkAgent("25459", { chain: "arbitrum" }); ``` #### HTTP API ```bash # Query parameter curl https://valiron-edge-proxy.onrender.com/operator/agent/25459?chain=monad ``` ### Querying Supported Chains ```bash curl https://valiron-edge-proxy.onrender.com/operator/health ``` Returns: ```json { "status": "ok", "supportedChains": ["ethereum", "monad", "arbitrum", "..."], "defaultChain": "ethereum" } ``` --- ## Errors Common error scenarios, status codes, and guidance on how to handle them. ### HTTP Status Codes | Status | Meaning | Action | |--------|---------|--------| | 200 | Success | Process the response | | 400 | Bad request | Check your request parameters | | 401 | Unauthorized | Verify your API key or credentials. **Do not retry.** | | 403 | Forbidden | You do not have access. **Do not retry.** | | 404 | Not found | Agent ID does not exist in the ERC-8004 registry | | 429 | Too many requests | **Stop immediately.** Honor the `Retry-After` header. | | 500 | Internal server error | Retry with exponential backoff | | 502 | Bad gateway | Retry after a short delay | | 503 | Service unavailable | Retry after `Retry-After` header duration | ### SDK Error Handling The SDK throws typed errors that you can catch: ```typescript import { ValironSDK } from "@valiron/sdk"; const valiron = new ValironSDK(); try { const profile = await valiron.getAgentProfile("99999"); } catch (error) { if (error.status === 404) { // Agent not registered — register via ERC-8004 first } else if (error.status === 429) { // Rate limited — wait and retry const retryAfter = error.headers?.["retry-after"]; await sleep(parseInt(retryAfter || "5") * 1000); } else { // Unexpected error — log and retry with backoff console.error(error.message); } } ``` ### Retry Strategy When retrying requests, follow this pattern: ```typescript async function withRetry(fn: () => Promise, maxRetries = 3): Promise { for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (error) { // Never retry auth errors if (error.status === 401 || error.status === 403) throw error; // Never retry client errors (except 429) if (error.status >= 400 && error.status < 500 && error.status !== 429) throw error; if (attempt === maxRetries) throw error; // Exponential backoff: 1s, 2s, 4s const delay = Math.pow(2, attempt) * 1000; await new Promise((r) => setTimeout(r, delay)); } } throw new Error("Unreachable"); } // Usage const profile = await withRetry(() => valiron.getAgentProfile("25459")); ``` ### Common Issues #### "Agent not found" (404) The agent ID is not registered in the ERC-8004 Identity Registry on the specified chain. Ensure: - The agent has been minted in the Identity Registry - You are querying the correct chain (`?chain=monad`, etc.) - The agent ID is the correct ERC-721 token ID (numeric string) #### "No behavioral data" (sandbox result is null) The agent has not been evaluated in the sandbox yet. Trigger a sandbox test: ```typescript await valiron.triggerSandboxTest("YOUR_AGENT_ID"); ``` #### Timeout errors The default SDK timeout is 5 seconds. For sandbox tests (which run real evaluations), increase it: ```typescript const valiron = new ValironSDK({ timeout: 30000 }); // 30 seconds ``` #### Chain mismatch If the agent is registered on Monad but you query Ethereum (the default), it will return 404. Always specify the correct chain: ```typescript const valiron = new ValironSDK({ chain: "monad" }); ``` --- ## Operator Dashboard Dashboard URL: https://www.valiron.co/dashboard (JWT-authenticated) The Operator Dashboard is a web interface for managing your Valiron integration. All dashboard features require signing in with an operator account. ### Getting Access 1. Go to https://www.valiron.co/dashboard and create an account 2. Copy your one-time API key (shown once at registration) ### Dashboard Pages **Overview** (`/dashboard`) — Landing page with revenue, calls, agents, latency stats, recent activity, and quick start guide. **Agents** (`/dashboard/agents`) — Every AI agent that has called your API. Sort by last seen, calls, spend, or errors. Click to drill into per-agent detail with endpoint breakdown and recent calls. **Analytics** (`/dashboard/analytics`) — Revenue and usage analytics. Daily revenue bar chart (7/30/90 day ranges), today's stats, top endpoints ranked by volume. **Call Logs** (`/dashboard/logs`) — Paginated log of every API call. Each row shows timestamp, agent, chain, endpoint, status code, cost, latency, session ID. Filter by time range. **API Keys** (`/dashboard/keys`) — Generate, copy, and revoke operator API keys (`val_op_` prefix). New keys are shown once — copy immediately. **Make API Agent-Ready** (`/dashboard/endpoints`) — Create hosted wrappers for existing APIs. Each wrapper has: public path, HTTP method, upstream API base URL, price per call, x402/MPP protocol, payment network, optional trust checks, rate limit, upstream auth, and description. Removing a wrapper soft-deletes it. **API Playground** (`/dashboard/playground`) — Test how Valiron evaluates different agents against your endpoints without writing code or sending real traffic. - Pick a chain (Ethereum, Monad, Arbitrum, Base, Avalanche) - Select a sample agent (good/bad/zero reputation) or enter a custom agent ID - Build a request (method, path). Required headers are injected automatically; expand "Advanced options" for custom headers, query params, or body - **Dry-run mode**: Returns trust evaluation (tier, route, price, on-chain score) without forwarding the request - **Standard mode**: Performs the full trust evaluation and logs the call. If the endpoint has an upstream API base URL, forwards the request to the operator's backend with trust headers. If no base URL is set, returns trust evaluation only. - History sidebar saves the last 20 requests with replay **Settings** (`/dashboard/settings`) — Update name. View plan, fee rate, and account info. **Admin** (`/dashboard/admin`, admin-only) — Platform-wide stats, all operators table with drill-down. ### Dashboard API Endpoints (JWT-authenticated) All dashboard endpoints require `Authorization: Bearer `. Get a JWT via `POST /operator/login`. ``` POST /operator/register Body: { "email": "...", "password": "...", "name": "..." } Returns: { operator, apiKey } — apiKey shown once POST /operator/login Body: { "email": "...", "password": "..." } Returns: { operator, token } GET /operator/me — current operator profile PATCH /operator/me — update name GET /operator/keys — list API keys POST /operator/keys/rotate — generate new key (body: { "label": "..." }) DELETE /operator/keys/{keyId} — revoke key GET /operator/endpoints — list registered endpoints POST /operator/endpoints — register endpoint (body: { path, method, pricePerCall, description?, rateLimit?, targetUrl? }) DELETE /operator/endpoints/{endpointId} — deactivate endpoint GET /operator/analytics/stats — aggregate stats GET /operator/analytics/revenue?days=30 — daily revenue time series GET /operator/analytics/top-endpoints?limit=10 — top endpoints by volume GET /operator/analytics/agents?sortBy=lastSeen&limit=50&offset=0 — paginated agent summaries GET /operator/analytics/agents/{agentId} — single agent detail GET /operator/analytics/logs?limit=50&offset=0&days=7 — paginated call logs POST /operator/playground — test request as simulated agent Body: { method, path, headers?, body?, agentId, chain?, dryRun? } Returns: { statusCode, statusText, responseHeaders, responseBody, responseMs, costCharged, route, tierResolved } ``` ### Integration Workflow 1. **Dashboard**: Create account → copy API key 2. **SDK middleware**: Install `@valiron/sdk` → add middleware to gate agent traffic 3. **Playground**: Test agent evaluations before going live 4. **Monitor**: Track agents, revenue, and logs in the dashboard ### Separate product: API Scaffolding Valiron's core product is middleware deployed within the API seller's backend. API Scaffolding is a separate product for organizations that require a hosted, agent-facing wrapper URL for an existing HTTPS API. It can serve as an evaluation path before adopting a first-party backend integration protected by Valiron middleware. Agents call: ```text https://valiron-edge-proxy.onrender.com/wrap/{operatorId}/{path} ``` Wrapper config fields include `path`, `method`, `targetUrl` (upstream API base URL), `pricePerCall`, `paymentProtocol` (`x402` or `mpp`), `paymentNetwork` (`eip155:8453`, `eip155:84532`, `tempo:4217`, or `tempo:42431`), `payoutAddress`, `trustEnabled`, `rateLimit`, and optional upstream auth fields. Free wrappers forward directly. x402 wrappers use `402` + `X-PAYMENT`; MPP wrappers use `WWW-Authenticate: Payment` + `Authorization: Payment`. --- ## Plans & Limits | Feature | Free | Pro | |---------|------|-----| | Gated endpoints | 3 | Unlimited | | Sandbox tests / day | 5 | Unlimited | | Webhooks | — | ✓ | | Proxy gateway | — | ✓ | | Analytics & logs | — | ✓ | | Evaluation history | — | ✓ | | Custom tier thresholds | — | ✓ | Pro plan requires an operator API key (`val_op_` prefix) from the Operator Dashboard. --- ## Proxy Gateway (Pro) Forward requests through Valiron's edge proxy instead of calling your origin directly. The proxy enforces trust gates, logs requests, and blocks SSRF attacks (private IPs, cloud metadata endpoints). ```typescript const result = await valiron.proxy({ agentId: "25459", targetUrl: "https://your-api.com/data", method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query: "example" }), }); ``` #### ProxyRequest | Field | Type | Required | Description | |-------|------|----------|-------------| | `agentId` | string | yes | Agent to gate | | `targetUrl` | string | yes | Your origin URL to forward to | | `method` | string | no | HTTP method (default: GET) | | `headers` | Record | no | Headers to forward | | `body` | string | no | Request body | Returns: `ProxyResponse` with `statusCode`, `responseHeaders`, `responseBody`, `responseMs`, `costCharged`, `route`, `tierResolved`. > **SSRF Protection:** The proxy blocks requests to private IPs (10.x, 172.16-31.x, 192.168.x), localhost, link-local addresses, and cloud metadata endpoints (169.254.169.254). --- ## Key-Based Agents For Web2 agents that don't have on-chain identities, Valiron supports key-based authentication using EIP-191 challenge-response. **How it works:** 1. Agent sends a request with `x-agent-address: 0x...` header 2. Valiron returns a challenge nonce 3. Agent signs the nonce with their private key 4. Valiron verifies the signature and creates a `KeyAgentProfile` The SDK auto-detects key-based agents from the `x-agent-address` header. No configuration needed. New key agents are automatically sandbox-evaluated on first gated request. Middleware allows key agents when verified and score >= minScore. Use `triggerKeyAgentSandbox(address)` or `POST /operator/trigger-sandbox-key/{address}` to trigger manually. #### KeyAgentProfile | Field | Type | Description | |-------|------|-------------| | `agentAddress` | string | Ethereum-style address used as the key-based agent identifier | | `verified` | boolean | Whether the agent proved key ownership through challenge-response | | `score` | number \| null | Behavioral score once sandbox evaluation has run | | `tier` | string \| null | Moody's-style trust tier once scored | | `riskLevel` | string \| null | GREEN / YELLOW / RED once scored | | `route` | string \| null | Route decision once scored | | `icebreaker` | object \| null | Optional ownership context from Icebreaker | | `reasons` | string[] | Human-readable trust explanation | | `timestamp` | string | ISO timestamp for the profile response | --- ## World ID Methods Verify agent-human linkage via Worldcoin's zero-knowledge proof system. ### verifyWorldId(agentId, proof) Submit a World ID proof for verification. ```typescript const result = await valiron.verifyWorldId("25459", { merkle_root: "0x...", nullifier_hash: "0x...", proof: "0x...", signal: "0x...", }); ``` ### getWorldIdStatus(agentId) Check if an agent has a verified World ID. ```typescript const status = await valiron.getWorldIdStatus("25459"); // { verified: true, verifiedAt: "2025-01-15T...", level: "orb" } ``` ### getWorldIdProfile(agentId) Get full World ID profile including verification details. ```typescript const profile = await valiron.getWorldIdProfile("25459"); ``` --- ## Telemetry The SDK optionally collects anonymous usage metrics (gate calls, latency, error rates). Telemetry is opt-in and can be fully disabled. ### Configuration ```typescript const valiron = new ValironSDK({ telemetry: { enabled: false, // Disable entirely sampleRate: 0.1, // Sample 10% of events handler: (event) => { // Custom handler myAnalytics.track(event); }, }, }); ``` #### TelemetryConfig | Field | Type | Default | Description | |-------|------|---------|-------------| | `enabled` | boolean | `true` | Enable/disable telemetry | | `sampleRate` | number | `1.0` | Fraction of events to sample (0–1) | | `handler` | function | — | Custom event handler | --- ## Response Types ### GateResult Returned by `gate()` and middleware. The core trust decision object. | Field | Type | Description | |-------|------|-------------| | `allowed` | boolean | Whether the agent is allowed access | | `tier` | string | Trust tier (AAA–C) | | `riskLevel` | string | GREEN / YELLOW / RED | | `route` | string | `prod` / `prod_throttled` / `sandbox` / `sandbox_only` | | `score` | number | Composite trust score (0–100) | | `agentId` | string | The evaluated agent ID | | `chain` | string | Blockchain network | | `signals` | object | Individual signal results | ### AgentProfile Returned by `getAgentProfile()`. Full on-chain agent details. | Field | Type | Description | |-------|------|-------------| | `agentId` | string | ERC-8004 token ID | | `owner` | string | Wallet address of the agent owner | | `tier` | string | Current trust tier | | `riskLevel` | string | Current risk level | | `reputation` | object | On-chain reputation data | | `sandbox` | object | Latest sandbox test results | | `worldId` | object | World ID verification status | | `icebreaker` | object | Icebreaker attestation data | ### Request Headers Headers attached to proxied/gated requests: | Header | Description | |--------|-------------| | `x-agent-id` | The agent's ERC-8004 token ID | | `x-agent-address` | The agent's wallet address (key-based agents) | | `x-valiron-tier` | Resolved trust tier | | `x-valiron-route` | Route decision | | `x-valiron-risk` | Risk level | ### All Exports ```typescript import { ValironSDK, ValironOperator, ValironClient, createValironGate, valironFastifyPlugin, createValironNextMiddleware, valironGateCheck, isValidAddress, generateChallenge, } from "@valiron/sdk"; ``` --- ## Middleware Error Responses All middleware (Express, Fastify, Next.js, generic) returns consistent error responses: | Status | When | Body | |--------|------|------| | 401 | No agent ID found in request | `{ error: "No agent identity provided" }` | | 403 | Agent denied by trust gate | `{ error: "Access denied", tier, riskLevel, route }` | | 403 | New agent pending evaluation | `{ error: "Agent pending evaluation", retryAfterMs: 30000 }` | | 503 | Valiron service unavailable | `{ error: "Trust evaluation unavailable" }` | > **Fail-closed:** When the Valiron service is unreachable, middleware returns 503 — it never fails open and never allows unverified agents through. --- ## Links - Summary (llms.txt): https://valiron.co/llms.txt - Full docs (llms-full.txt): https://www.valiron.co/llms-full.txt - Website: https://valiron.co - SDK: https://www.npmjs.com/package/@valiron/sdk - API Base URL: https://valiron-edge-proxy.onrender.com