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/sdk

Zero 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 Base

getScore()

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/json

Request 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 cycle

Request 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.

MethodPathAuthDescription
GET/api/score/:type/:idNoneLatest score + EAS UID per vertical
GET/api/score/:type/:id/breakdownx402 $0.01Full signal breakdown
POST/api/trace/submitBearer tokenSubmit solver execution trace
POST/api/vertical/requestNoneRequest onboarding for unknown vertical

Registry types

registryType determines how Verity resolves an agent's canonical identity and which data sources are queried.

TypeplatformIdVerticals scoredNotes
erc8004ERC-721 token ID (uint256)Economic, Base Layer, SolverERC-8004 IdentityRegistry on any supported chain
virtualsProvider wallet address (0x…)EconomicVirtuals Protocol ACP — task completion rate as BSS signal
fetchaiAgentverse agent address (agent1q…)Base LayerFetch.ai Almanac — scores via ERC-8004 feedback when available
wardenSpace ID (uint64 string)SolverWarden Protocol — space-as-agent identity on chainId 8765
walletEVM wallet address (0x…)Economic, GovernanceRaw EVM wallet — Polymarket trader or Sky/MakerDAO governance delegate
olasOlas token ID (uint256)Base LayerOlas 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 →