Skip to content

API Reference

RunTimeAdmin edited this page Oct 23, 2026 · 24 revisions

API Reference

**Referenced Files in This Document** - [index.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/index.js) - [http-helpers.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/http-helpers.js) - [README.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/README.md)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document describes Sigvara’s oracle REST API endpoints relevant to attestation submission, reputation scoring, and evidence access. It covers:

  • /attest — submit an attestation for a Sigvara agent.
  • /score/:didHash — preview the computed score for an agent without writing to chain.
  • /evidence/:didHash — retrieve the payments behind an agent’s score with Merkle proofs.

It also documents authentication, rate limiting, error handling, security considerations, input validation, and practical request/response examples.

Project Structure

The oracle is implemented as a Node.js HTTP server that routes requests directly in its main handler. Authentication, body parsing, credential loading, and rate limiting are shared helpers.

graph TB
Client["API Consumer"] --> Server["Oracle HTTP Server<br/>index.js"]
Server --> Helpers["HTTP Helpers<br/>http-helpers.js"]
Server --> Chain["Chain Layer"]
Server --> Payments["Payments Verification"]
Server --> Scoring["Scoring Logic"]
Server --> Store["Persistent State"]
Server --> Merkle["Merkle Utilities"]
Server --> Cache["Response Cache"]
Loading

Diagram sources

Section sources

Core Components

  • Request router: Centralized HTTP handler dispatches paths such as /attest, /score/:didHash, /evidence/:didHash, /flag, /link, /jobs/<address>, /badge/<address>.svg, /metrics, /epoch, and divergence endpoints.
  • Authentication: Bearer tokens loaded from environment variables; supports a legacy admin token and named per-service tokens.
  • Rate limiting: In-memory fixed-window limiter keyed by client address (with X-Forwarded-For support when proxied through loopback).
  • Payment verification: Optional verified-payment path where a transaction hash proves payment to the agent’s operator address.
  • Scoring inputs: Attestations, flags, external ERC-8004 feedback, measured fee volume, activity, and propagation factors.
  • Evidence and Merkle proofs: Payment events are exposed with a Merkle root and leaf structure suitable for on-chain verification.

Section sources

Architecture Overview

The oracle exposes read-only and write endpoints. Read endpoints (/score, /evidence) are intentionally unauthenticated but rate-limited. Write endpoints require bearer-token authorization and additional validation.

sequenceDiagram
participant C as "Client"
participant S as "Server index.js"
participant H as "Helpers http-helpers.js"
participant P as "Payments"
participant CH as "Chain"
C->>S : POST /attest { didHash, success, packetId }
S->>H : identifyCaller(headers, credentials)
alt Positive + verified payments enabled
S->>P : verifyPayment(txHash, agentAddress)
P-->>S : credited payer, amount, settledAt
else Negative or payments disabled
S->>S : require bearer token
end
S->>S : check cooldown, update attestations
S->>CH : getAgentInfo(didHash)
CH-->>S : agent info
S-->>C : 200 { didHash, attester, totals, payment? }
Loading

Diagram sources

Detailed Component Analysis

Endpoint: POST /attest

Submits an attestation for a Sigvara agent. The endpoint supports two modes:

  • Verified-payment mode: A positive attestation can be submitted without a bearer token if it includes a valid payment transaction proving money moved to the agent’s operator address. Negative attestations still require a bearer token.
  • Token-only mode: When payment verification is not required, a bearer token is always required, and the caller must provide an attester identifier.

Request

  • Method: POST
  • Path: /attest
  • Headers:
    • Authorization: Bearer <token> (required unless positive + verified-payment mode)
    • Content-Type: application/json
  • Body fields:
    • didHash (string, required): 32-byte hex identity hash of the agent.
    • success (boolean, required): Whether the work was successful.
    • packetId (string, optional): An optional UUID-like identifier used as corroboration when payment verification is enabled.
    • payment.txHash (string, optional when payment verification is enabled): Transaction hash used to prove payment to the agent’s operator address.
    • attester (string, optional): Unique ID for the attestation source; required when payment verification is disabled.

Response

  • Success: 200 OK
    • Fields include didHash, attester, updated attestation totals, and optionally payment.txHash and payment.amount.
  • Errors:
    • 400 Bad Request: Missing or invalid fields, unknown didHash, malformed packetId.
    • 401 Unauthorized: Missing or invalid bearer token when required.
    • 402 Payment Required: Invalid payment, self-payment, or other payment-related failure.
    • 409 Conflict: Settlement already credited.
    • 429 Too Many Requests: Rate limited or attestation cooldown active.
    • 502 Bad Gateway: Upstream RPC failure while reading agent info or verifying payment.

Authentication Rules

  • If payment verification is enabled and success === true, no bearer token is required because the payment itself acts as proof.
  • Negative attestations (success === false) always require a bearer token.
  • When payment verification is disabled, a bearer token is always required and attester must be provided.

Input Validation

  • didHash must be present.
  • attester is required when payment verification is disabled.
  • With payment verification enabled, txHash is validated against the chain and linked to the agent’s operator address.
  • Self-payments are rejected.
  • Cooldown prevents repeated attestations from the same attester to the same agent within a configured window.

Practical Example

  • Request:
    POST /attest
    Authorization: Bearer <token>
    Content-Type: application/json
    
    {
      "didHash": "0x...64-hex...",
      "success": true,
      "packetId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "payment": {
        "txHash": "0x..."
      }
    }
    
  • Response:
    {
      "didHash": "0x...64-hex...",
      "attester": "0x...",
      "successful": 1,
      "total": 1,
      "payment": {
        "txHash": "0x...",
        "amount": "1000000000000000000"
      }
    }

Section sources


Endpoint: GET /score/:didHash

Returns a preview of the computed score for an agent without writing to chain. This endpoint is unauthenticated but rate-limited.

Request

  • Method: GET
  • Path: /score/:didHash
  • Query parameters: None defined for this endpoint.
  • Path parameter:
    • didHash (string, required): 32-byte hex identity hash of the agent.

Response

  • Success: 200 OK
    • Fields include:
      • didHash
      • status
      • scores
      • attestations
      • weighted (present only when payment verification is enabled), including weighted attestations, distinct payers, activity, trust weight, half-life days, and max per payer.
      • flags and flagWeight
      • erc8004AgentId (when linked)
  • Errors:
    • 429 Too Many Requests: Rate limited.
    • 502 Bad Gateway: Upstream RPC failure reading agent info.
    • 500 Internal Server Error: Unexpected computation failure.

Practical Example

  • Request:
    GET /score/0x...64-hex...
    
  • Response:
    {
      "didHash": "0x...64-hex...",
      "status": 1,
      "scores": { ... },
      "attestations": { "successful": 10, "total": 12 },
      "weighted": {
        "attestations": { "successful": 8, "total": 10 },
        "distinctPayers": 5,
        "activity": 0.95,
        "trustWeight": 0.6,
        "halfLifeDays": 30,
        "maxPerPayer": 100
      },
      "flags": 1,
      "flagWeight": 0.0012,
      "erc8004AgentId": "123"
    }

Section sources


Endpoint: GET /evidence/:didHash

Retrieves the payments behind an agent’s score, including Merkle proofs. This endpoint is deliberately unauthenticated so anyone can audit the evidence.

Request

  • Method: GET
  • Path: /evidence/:didHash
  • Path parameter:
    • didHash (string, required): 32-byte hex identity hash of the agent.

Response

  • Success: 200 OK
    • Returns JSON containing the agent’s payment events and Merkle root information.
  • Errors:
    • 400 Bad Request: Malformed didHash.
    • 429 Too Many Requests: Rate limited.

Merkle Proof Verification

  • The response includes a Merkle root and leaf structure committed to by the oracle.
  • Consumers can independently recompute the root over the payment events and compare it with the value stored on-chain.
  • The response names the committed fields and leaf order so verifiers do not need to infer them from implementation details.

Practical Example

  • Request:
    GET /evidence/0x...64-hex...
    
  • Response:
    {
      "didHash": "0x...64-hex...",
      "root": "0x...",
      "committedFields": ["txHash","amount","payer","settledAt","blockNumber"],
      "events": [
        {
          "txHash": "0x...",
          "amount": "1000000000000000000",
          "payer": "0x...",
          "settledAt": 1700000000,
          "blockNumber": 12345678
        }
      ]
    }

Section sources


Additional Endpoints Referenced

  • /flag and /flag/resolve — Token-gated flag management affecting scores.
  • /link — Link a Sigvara agent to an ERC-8004 identity.
  • /jobs/<address> — Observation-only ERC-8183 jobs data.
  • /badge/<address>.svg — Embeddable SVG badge showing finalized score state.
  • /metrics — Prometheus metrics.
  • /epoch — Manual epoch trigger (token-gated).
  • /divergence and /divergence/:didHash — Checker-mode disagreement records.

These endpoints share the same authentication and rate-limiting patterns described below.

Section sources

Dependency Analysis

The following diagram shows how the core endpoints depend on shared modules.

graph LR
A["/attest"] --> H["identifyCaller()"]
A --> R["rateLimited()"]
A --> V["verifyPayment()"]
A --> S["store attestations"]
B["/score/:didHash"] --> H
B --> R
B --> M["measuredFactorsFor()"]
B --> C["computeScore()"]
E["/evidence/:didHash"] --> R
E --> ME["getPaymentEvents()"]
E --> MR["buildEvidenceBody()"]
Loading

Diagram sources

Section sources

Performance Considerations

  • /score performs multiple chain reads (agent info, payer standing, external score when linked). It is rate-limited even though it is public.
  • /evidence may rebuild a Merkle tree over payment events on cache misses; it is rate-limited to bound first-request cost.
  • /attest validates payments and updates persistent state; it is rate-limited and uses a per-attester cooldown.
  • Metrics expose counters for rate limits, RPC errors, attestations accepted/rejected, and more.

Troubleshooting Guide

Authentication Failures

  • 401 Unauthorized on /attest occurs when:

    • A negative attestation is submitted without a bearer token.
    • Payment verification is disabled and no bearer token is provided.
    • The bearer token does not match any configured credential.
  • Credentials are loaded from:

    • ORACLE_ADMIN_TOKEN (legacy admin token).
    • ORACLE_TOKEN_<NAME> variables (per-service tokens).
  • Tokens are matched using constant-time comparison against Authorization: Bearer <token>.

Section sources

Rate Limiting

  • Global fixed-window rate limiter:

    • Window: 60 seconds.
    • Max: 60 requests per key per window.
    • Key: client IP, with X-Forwarded-For trusted only when the connection arrives via loopback.
  • Responses:

    • 429 Too Many Requests with { error: "Rate limited" }.

Section sources

Attestation-Specific Errors

  • 400 Bad Request:

    • Missing didHash.
    • Missing attester when payment verification is disabled.
    • Unknown didHash.
    • Malformed packetId.
  • 402 Payment Required:

    • Invalid payment.
    • Self-payment detected.
  • 409 Conflict:

    • Settlement already credited.
  • 429 Too Many Requests:

    • Rate limited.
    • Attestation cooldown active (includes remainingSeconds and cooldownMs).
  • 502 Bad Gateway:

    • RPC failure reading agent info or verifying payment.

Section sources

Score Endpoint Errors

  • 502 Bad Gateway:
    • Upstream RPC failure reading agent info.
  • 500 Internal Server Error:
    • Unexpected computation failure; generic message returned to avoid leaking upstream details.

Section sources

Evidence Endpoint Errors

  • 400 Bad Request:
    • Malformed didHash.
  • 429 Too Many Requests:
    • Rate limited.

Section sources

Conclusion

Sigvara’s oracle API provides secure attestation submission, transparent reputation scoring, and auditable evidence with Merkle proofs. Authentication is flexible, supporting both legacy admin tokens and per-service bearer tokens. Public read endpoints are intentionally open but rate-limited. Consumers should handle 429, 401, 402, 409, 502, and 500 responses appropriately, validate inputs, and use /evidence for independent verification of the oracle’s claims.

Appendices

Authentication Methods

  • Admin token: ORACLE_ADMIN_TOKEN maps to the admin credential name.
  • Named tokens: ORACLE_TOKEN_<NAME> variables define per-service credentials; names are lowercased.
  • Header format: Authorization: Bearer <token>.
  • Policy enforcement: Non-loopback binds require at least one configured credential; otherwise startup fails.

Section sources

Rate Limiting Policy

  • Fixed window: 60 seconds.
  • Maximum: 60 requests per key per window.
  • Key derivation:
    • Direct socket address for non-loopback connections.
    • Last entry in X-Forwarded-For for loopback connections.

Section sources

Security Considerations and Best Practices

  • Always set bearer tokens before exposing the oracle publicly.
  • Prefer per-service tokens for better revocation granularity.
  • Use /evidence to independently verify Merkle roots and payment events.
  • Treat 502 as upstream failures and retry with backoff.
  • Respect 429 responses and implement exponential backoff.
  • Validate all inputs on the client side to reduce unnecessary retries.
  • Avoid sending sensitive data in logs or error messages.

Overview

Clone this wiki locally