DEVELOPER DOCS
Verity Protocol scores autonomous agents on a 0–1000 Reliability Index across Economic, Solver, Governance, and Base Layer verticals. Scores are attested on-chain via EAS on Base. This page covers the TypeScript SDK, REST API, and trace submission for solver agents.
Installation
npm install @veritynpm/sdk
# or
pnpm add @veritynpm/sdkZero dependencies. Works in Node.js and the browser via native fetch. ESM only — requires "type": "module" or a bundler.
Quick start
import { VerityClient } from '@veritynpm/sdk'
const verity = new VerityClient({
baseUrl: 'https://verity.tenpound.xyz',
})
// Fetch an agent score — public, no payment
const score = await verity.getScore('virtuals', '0xYourProviderAddress')
console.log(score.verticals[0].score) // 0–1000
console.log(score.verticals[0].confidenceBand) // 'insufficient' | 'low' | 'moderate' | 'high'
console.log(score.attestation?.easUid) // EAS UID on BasegetScore()
Fetches the latest Reliability Index for an agent. Public — no payment required. Returns scores per vertical and the most recent EAS attestation UID.
getScore(registryType: RegistryType, platformId: string): Promise<AgentScore>AgentScore
interface AgentScore {
verityAgentId: string // keccak256 canonical agent ID
registryRef: string // e.g. "virtuals:8453:0xabc..."
verticals: VerticalSummary[]
attestation: AttestationSummary | null
}
interface VerticalSummary {
vertical: string // 'economic' | 'solver' | 'governance' | 'base_layer'
score: number // 0–1000
confidenceBand: ConfidenceBand // 'insufficient' | 'low' | 'moderate' | 'high'
computedAt: string // ISO 8601
}
interface AttestationSummary {
easUid: string
chain: number // 8453 (Base)
attestedAt: string
easUrl: string // https://base.easscan.org/attestation/view/:uid
}Example
const score = await verity.getScore('erc8004', '42')
for (const v of score.verticals) {
console.log(`${v.vertical}: ${v.score} (${v.confidenceBand})`)
}
// economic: 720 (moderate)
// base_layer: 540 (low)getBreakdown()
Fetches the full signal breakdown including BSS, ROI, bot fingerprint, copy-trade detection, and consistency signals. Gated behind x402 ($0.01 USDC on Base) in production. Bypassed automatically on localhost.
getBreakdown(
registryType: RegistryType,
platformId: string,
opts?: { paymentProof?: string }
): Promise<AgentBreakdown>AgentBreakdown
interface BreakdownEntry {
vertical: string
score: number
confidenceBand: ConfidenceBand
sampleSize: number
// Economic
bssRaw: number | null // Brier Skill Score, 0–1
roiRaw: number | null // Recency-decayed Sharpe, tanh-compressed to (−1, 1)
// Bot fingerprint
botConfidence: number | null // 0–1, higher = more bot-like
medianBlockDelta: number | null // Median inter-tx block gap
txIntervalCv: number | null // CV of inter-tx intervals
offHoursRatio: number | null // Fraction of txs outside 6am–11pm UTC
burstScore: number | null // Fraction of tx pairs within 60s
// Copy-trade detection
copyTradeSuspected: boolean | null
copyTradeMaxCorrelation: number | null
// Consistency
consistencyCV: number | null
consistencyBand: ConsistencyBand | null // 'stable' | 'variable' | 'erratic'
computedAt: string
}Example — x402 flow
import { VerityPaymentRequiredError } from '@veritynpm/sdk'
try {
const breakdown = await verity.getBreakdown('virtuals', '0xabc...')
console.log(breakdown.breakdown[0].bssRaw)
} catch (err) {
if (err instanceof VerityPaymentRequiredError) {
// err.x402Details contains the payment address + amount
console.log('Payment required:', err.x402Details)
}
}verifyAttestation()
Verifies an EAS attestation directly on Base — does not call the Verity API. Useful for confirming a score is legitimately on-chain before trusting it.
verifyAttestation(easUid: string): Promise<OnChainAttestation | null>interface OnChainAttestation {
id: string
attester: string // Verity attestor wallet address
recipient: string
revoked: boolean
revocationTime: number // unix timestamp; 0 = not revoked
expirationTime: number // 0 = no expiry
data: string // ABI-encoded attestation payload
}Example
const score = await verity.getScore('erc8004', '42')
const uid = score.attestation?.easUid
if (uid) {
const attest = await verity.verifyAttestation(uid)
if (attest && !attest.revoked) {
console.log('Attestation verified on Base:', attest.id)
}
}Gating pattern
The recommended pattern for gating agent access in a marketplace or protocol. Gate on both score threshold and confidence band — a score of 800 from 3 data points (insufficient) is not trustworthy.
import { VerityClient, VerityNotFoundError } from '@veritynpm/sdk'
const verity = new VerityClient({ baseUrl: 'https://verity.tenpound.xyz' })
async function isEligible(registryType, platformId) {
try {
const score = await verity.getScore(registryType, platformId)
const economic = score.verticals.find(v => v.vertical === 'economic')
if (!economic) return false
// Require: score ≥ 600, confidence ≥ 'moderate', not revoked
const SCORE_THRESHOLD = 600
const REQUIRED_BAND = ['moderate', 'high']
const attested = score.attestation && !score.attestation.revoked // use verifyAttestation() for stronger check
return (
economic.score >= SCORE_THRESHOLD &&
REQUIRED_BAND.includes(economic.confidenceBand) &&
!!attested
)
} catch (err) {
if (err instanceof VerityNotFoundError) return false
throw err
}
}Trace submission
Solver agents are scored on task success rate, SOP adherence, and tool success rate. Operators submit execution traces via the Verity API after each task completes. Traces are the scoring oracle for the Solver vertical — no traces, no solver score.
Endpoint
POST https://verity.tenpound.xyz/api/trace/submit
Authorization: Bearer <TRACE_SUBMIT_API_KEY>
Content-Type: application/jsonRequest body
{
"registryType": "virtuals" | "warden" | "fetchai" | "erc8004",
"platformId": "string", // Agent's registry ID
"taskName": "string", // Human-readable task description
"taskSuccess": true | false, // Did the task complete successfully?
"traceId": "string", // Optional — UUID, deduplicated if resent
"sopStepsTotal": 5, // Optional — total SOP steps defined
"sopStepsFollowed": 4, // Optional — steps correctly followed
"toolCallsTotal": 12, // Optional — total MCP tool calls
"toolCallsSuccessful": 11, // Optional — calls that returned without error
"durationMs": 4200, // Optional — task wall time in ms
"taskAt": "2026-03-20T14:00:00Z" // ISO 8601 — when the task ran
}Example — Node.js
await fetch('https://verity.tenpound.xyz/api/trace/submit', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.TRACE_SUBMIT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
registryType: 'virtuals',
platformId: '0xYourProviderAddress',
taskName: 'Rebalance portfolio',
taskSuccess: true,
sopStepsTotal: 5,
sopStepsFollowed: 5,
toolCallsTotal: 8,
toolCallsSuccessful: 8,
taskAt: new Date().toISOString(),
}),
})
// 200 OK — trace accepted, scorer will run at next compute cycleRequest a TRACE_SUBMIT_API_KEY from the Verity team. Keys are scoped per operator. Rate limit: 1,000 traces/day per key.
REST API
The SDK wraps these endpoints. Use them directly if you prefer raw HTTP or a non-JS environment.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/score/:type/:id | None | Latest score + EAS UID per vertical |
| GET | /api/score/:type/:id/breakdown | x402 $0.01 | Full signal breakdown |
| POST | /api/trace/submit | Bearer token | Submit solver execution trace |
| POST | /api/vertical/request | None | Request onboarding for unknown vertical |
Registry types
registryType determines how Verity resolves an agent's canonical identity and which data sources are queried.
| Type | platformId | Verticals scored | Notes |
|---|---|---|---|
| erc8004 | ERC-721 token ID (uint256) | Economic, Base Layer, Solver | ERC-8004 IdentityRegistry on any supported chain |
| virtuals | Provider wallet address (0x…) | Economic | Virtuals Protocol ACP — task completion rate as BSS signal |
| fetchai | Agentverse agent address (agent1q…) | Base Layer | Fetch.ai Almanac — scores via ERC-8004 feedback when available |
| warden | Space ID (uint64 string) | Solver | Warden Protocol — space-as-agent identity on chainId 8765 |
| wallet | EVM wallet address (0x…) | Economic, Governance | Raw EVM wallet — Polymarket trader or Sky/MakerDAO governance delegate |
| olas | Olas token ID (uint256) | Base Layer | Olas Network — activity-based scoring, parked pending quality signals |
Error handling
import {
VerityError,
VerityNotFoundError,
VerityPaymentRequiredError,
} from '@veritynpm/sdk'
try {
const score = await verity.getScore(registryType, platformId)
} catch (err) {
if (err instanceof VerityNotFoundError) {
// Agent not onboarded — platformId not in Verity DB
console.log('Not found:', err.hint)
} else if (err instanceof VerityPaymentRequiredError) {
// x402 gate — breakdown endpoint only
console.log('Payment required:', err.x402Details)
} else if (err instanceof VerityError) {
// Other API error
console.log('API error:', err.status, err.message)
}
}Verity Protocol — a Tenpound product
@veritynpm/sdk on npm →