@valiron/sdk
Official TypeScript SDK for Valiron — Trust Infrastructure for AI Agent Systems. Verify agent trustworthiness using on-chain reputation (ERC-8004) and behavioral analysis.
Installation
npm install @valiron/sdk
# or
pnpm add @valiron/sdkGetting Started
import { ValironSDK } from '@valiron/sdk';
const valiron = new ValironSDK();
// Quick routing check (defaults to Ethereum)
const route = await valiron.checkAgent('25459');
if (route === 'prod') {
// Allow full production access
}
// Query a specific chain
const monadRoute = await valiron.checkAgent('8348', { chain: 'monad' });
const baseRoute = await valiron.checkAgent('8348', { chain: 'base' });
// Or set default chain at construction
const monadValiron = new ValironSDK({ chain: 'monad' });
const profile = await monadValiron.getAgentProfile('8348');
console.log(profile.routing.finalRoute); // 'prod'
console.log(profile.localReputation?.tier); // 'AAA'
console.log(profile.onchainReputation.averageScore); // 92.5Supported Chains
Valiron is multichain. Set the default chain at construction or override per-call. All SDK methods accept an optional chain field.
// Set default chain at construction
const valiron = new ValironSDK({ chain: 'monad' });
await valiron.getAgentProfile('8348'); // Uses Monad
// Override per-call (takes precedence)
const valiron2 = new ValironSDK();
await valiron2.checkAgent('8348', { chain: 'base' }); // Base
await valiron2.checkAgent('25459', { chain: 'ethereum' }); // Ethereum
await valiron2.checkAgent('25459'); // Server defaultCore Concepts
Route Decisions
The SDK returns one of four routing decisions:
| Route | Meaning | Trust Tiers |
|---|---|---|
prod | Full access | AAA – BAA |
prod_throttled | Rate-limited access | BA – B |
sandbox | Agent under evaluation | Temporary |
sandbox_only | Access denied | CAA – C |
Trust Evaluation
Valiron evaluates agents using:
- On-chain Reputation — ERC-8004 feedback submitted by other organizations
- Behavioral Analysis — Sandbox evaluation of rate-limit compliance, error rates, and request patterns
- Credit Rating — Moody's-style scoring system (AAA to C)
Architecture
Request → SDK.checkAgent() → Valiron Operator API → Route Decision → Your AppWallet Resolution
When an agent pays via x402 or similar protocols, you receive a wallet address — not an agent ID. Valiron resolves wallets to ERC-8004 agent IDs using a multi-layer lookup:
- Redis — Fast cache of previously resolved wallet → agentId mappings
- Agent0 Subgraph — Queries The Graph (Ethereum, Base, Polygon) for on-chain agent registrations by wallet
- Fallback — Returns null if no agent owns the wallet
Wallet → Redis lookup → Agent0 subgraph → agentId (or null)Use resolveWallet() for the lightweight lookup, or getWalletProfile() to get the full trust profile in one call.
API Reference
Constructor
new ValironSDK(config?: ValironConfig)| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string | — | API key (reserved for future use) |
chain | SupportedChain | server default | Default blockchain network |
timeout | number | 5000 | Request timeout (ms) |
debug | boolean | false | Enable debug logging |
checkAgent(agentId, options?)
Quick routing check — returns just the route decision string.
const route = await valiron.checkAgent('25459');
// route: 'prod' | 'prod_throttled' | 'sandbox' | 'sandbox_only'
// With chain override
const monadRoute = await valiron.checkAgent('8348', { chain: 'monad' });getAgentProfile(agentId, options?)
Full trust profile combining on-chain identity, reputation, behavioral data, and routing.
const profile = await valiron.getAgentProfile('25459');
// Response includes:
// profile.identity — on-chain identity (wallet, name, endpoints)
// profile.onchainReputation — ERC-8004 feedback (count, averageScore)
// profile.localReputation — behavioral score, tier, riskLevel
// profile.routing — finalRoute, decision, reasons, signalsgetWalletProfile(wallet, options?)
Reverse-lookup a wallet address to get its trust profile.
const profile = await valiron.getWalletProfile('0x52ce...');
console.log(profile.routing.finalRoute);
// With chain override
const monadProfile = await valiron.getWalletProfile('0xABC...', { chain: 'monad' });resolveWallet(wallet, options?)
Lightweight wallet → agentId resolution without fetching 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.
const resolution = await valiron.resolveWallet('0x52ce...');
console.log(resolution.agentId); // '25459' or null
console.log(resolution.source); // 'redis' | 'subgraph' | 'cache' (in-memory) | 'none'
console.log(resolution.agentName); // 'MyAgent' (from subgraph, if available)
console.log(resolution.chainId); // 1 (from subgraph, if available)
// Then fetch the full profile if needed
if (resolution.agentId) {
const profile = await valiron.getAgentProfile(resolution.agentId);
}| Field | Type | Description |
|---|---|---|
wallet | string | The queried wallet address |
agentId | string | null | Resolved ERC-8004 agent ID, or null if not found |
source | ResolutionSource | "redis" | "subgraph" | "cache" | "none" |
chainId | number | null | Chain ID from the subgraph (if available) |
agentName | string | null | Agent name from the subgraph (if available) |
timestamp | string | ISO timestamp of the resolution |
triggerSandboxTest(agentId, options?)
Run real sandbox tests against an agent and compute a Valiron score.
const result = await valiron.triggerSandboxTest('25459');
console.log(result.valironScore); // 95
console.log(result.tier); // 'AAA'
console.log(result.riskLevel); // 'GREEN'
console.log(result.mode); // 'endpoint-probe' | 'sandbox-relay'
console.log(result.testSummary);
// { totalRequests, successCount, rateLimitCount, errorCount, avgLatencyMs }gate(agentId, options?)
Trust gate — single call combining on-chain reputation + sandbox tests. Designed to sit in front of payment protocols (x402 etc.). Returns an allow/deny decision with a combined score.
const result = await valiron.gate('25459');
console.log(result.allow); // true
console.log(result.score); // 95
console.log(result.tier); // 'AAA'
console.log(result.riskLevel); // 'GREEN'
console.log(result.sandboxRan); // true (first call) / false (cached)
// Custom threshold
const result2 = await valiron.gate('8348', {
minScore: 85, // require A tier or above
ttlMs: 3600_000, // re-test every hour
chain: 'monad', // chain override
});
if (result2.allow) {
// proceed to payment
} else {
console.log(result2.reasons); // ['Score 42 below threshold 85']
}| Option | Type | Default | Description |
|---|---|---|---|
minScore | number | 65 | Minimum score to allow (0–110) |
ttlMs | number | 86400000 | Cache TTL for sandbox results (ms) |
chain | SupportedChain | constructor default | Blockchain network override |
checkAgent() returns a route decision based on existing data. gate() actively runs sandbox tests (if stale/missing), computes a combined score, and returns a binary allow/deny — ideal for protecting payment endpoints.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 that need to commit behavioral state on-chain without accessing raw metrics.
const snapshot = await valiron.getAgentSnapshot('25459');
console.log(snapshot.snapshotHash); // '0x3a7f...' (opaque hash)
console.log(snapshot.previousHash); // '0x0' (genesis) or '0x8b2c...'
console.log(snapshot.encryptedDataUri); // IPFS CID or null
console.log(snapshot.interactionCount); // 15The snapshotHash is computed internally by Valiron from behavioral metrics. It is opaque — you cannot reverse it to raw metrics. Each hash references the previousHash, forming a chain. First evaluation gets "0x0".
Webhooks
Register a webhook to receive evaluation_complete events whenever Valiron evaluates an agent. The payload matches the getAgentSnapshot() response.
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/valiron", "agentIds": [42, 43]}'The agentIds filter is optional — omit it to receive events for all agents.
createValironGate(config)
Express-compatible middleware factory that wraps gate(). Drop it in front of your routes for automatic agent extraction, trust gating, and error responses.
import { ValironSDK, createValironGate } from '@valiron/sdk';
const valiron = new ValironSDK({ chain: 'monad' });
// Basic — uses x-agent-id header, minScore 65, 24h TTL
app.use('/api/paid', createValironGate({ sdk: valiron }));
// Custom threshold and TTL
app.use('/api/premium', createValironGate({
sdk: valiron,
minScore: 85,
ttlMs: 3600_000,
}));
// Custom agent ID extraction + hooks
app.use('/api/custom', createValironGate({
sdk: valiron,
extractAgentId: (req) => req.query.agent_id as string,
onAllow: (req, result) => {
console.log(`Allowed agent ${result.agentId} (score: ${result.score})`);
},
onDeny: (req, res, result) => {
res.status(403).json({
error: 'Insufficient trust score',
requiredTier: 'A',
currentTier: result.tier,
});
},
}));Dynamic Scoring
Valiron enables trust-based dynamic pricing for your API endpoints. Agents with lower trust scores pay more per request — covering the potential infrastructure damage they may cause — while highly trusted agents get discounted rates as a reward for good behavior.
This creates a self-balancing economic model: bad actors subsidize their own risk, and good actors are incentivized to maintain their reputation.
Pricing by Trust Tier
| Tier | Score Range | Risk | Example Price |
|---|---|---|---|
| AAA | 98–110 | Prime | $0.005 |
| AA | 92–97 | High grade | $0.005 |
| A | 85–91 | Upper medium | $0.008 |
| BAA | 75–84 | Medium | $0.010 |
| BA | 65–74 | Speculative | $0.025 |
| B | 50–64 | Highly speculative | $0.050 |
| CAA – C | 0–49 | Substantial risk | Blocked |
Implementation
Use the trust gate result to set per-request pricing. This example pairs Valiron with x402 payment headers:
import { ValironSDK, createValironGate } from '@valiron/sdk';
const valiron = new ValironSDK({ chain: 'monad' });
const trustGate = createValironGate({ sdk: valiron, minScore: 50 });
// Pricing table — bad agents pay more to offset infra risk
const PRICE_BY_TIER: Record<string, number> = {
AAA: 5, // $0.005
AA: 5, // $0.005
A: 8, // $0.008
BAA: 10, // $0.010
BA: 25, // $0.025
B: 50, // $0.050
};
function dynamicPricing(req: any, res: any, next: any) {
const tier = req.valiron?.tier || 'B';
const price = PRICE_BY_TIER[tier] ?? 50;
// Attach price to request for downstream payment check
req.priceMillicents = price;
// If payment header is missing, return 402 with tier-adjusted price
if (!req.headers['x-payment']) {
return res.status(402).json({
accepts: [{
scheme: 'exact',
maxAmountRequired: price,
payTo: '0x...',
network: 'monad',
}],
meta: { tier, score: req.valiron?.score },
});
}
next();
}
// Flow: Trust Gate → Dynamic Pricing → Handler
app.get('/api/data', trustGate, dynamicPricing, (req, res) => {
res.json({ data: 'Here you go', tier: req.valiron.tier });
});Error Handling
All SDK methods throw typed ValironError instances with a code field for programmatic handling.
import { ValironError } from '@valiron/sdk';
try {
const profile = await valiron.getAgentProfile('123');
} catch (error) {
if (error instanceof ValironError) {
switch (error.code) {
case 'TIMEOUT_ERROR': // Request timed out
case 'NETWORK_ERROR': // Could not reach API
case 'API_ERROR': // Non-2xx response (check error.statusCode)
}
}
}| Error Code | Meaning |
|---|---|
TIMEOUT_ERROR | Request exceeded the configured timeout (default 5000ms) |
NETWORK_ERROR | Could not reach the Valiron API (DNS, connection refused, etc.) |
API_ERROR | Server returned a non-2xx response — check error.statusCode |