Repository navigation
AI Framework Integration
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document explains how to integrate Sigvara with popular AI frameworks and build reputation-aware agents that verify counterparties before sensitive operations. It covers:
- SDK patterns for identity, challenge-response authentication, and reputation checks
- Patterns for LangChain, AutoGen, CrewAI, and TypeScript/Node.js integrations
- Checking another agent before paying or hiring it, in a LangChain tool or under an x402 client
- Building gated toolchains where trust is enforced before execution
- Configuration templates, environment variables, and deployment considerations
- Performance optimization strategies for high-frequency reputation checks
- Testing approaches and debugging techniques for reputation-related issues
The integration pattern is consistent across frameworks:
- Create a deterministic agent identity at startup
- Audit actions by including the agent DID in audit events
- Verify signatures and reputation thresholds before trusting or delegating work
The SDK described here is 1.0.0-alpha.19, published to npm on 10 November 2026. New since 1.0.0-alpha.18: a spent gate nonce stays marked past its window, registerAgent derives the didHash when no event decodes, and sigvaraX402Fetch refuses a 402 whose header or body is over 64 KiB or that makes more than 16 offers, and checks at most four sellers at a time. New since 1.0.0-alpha.17: sigvara_verify_evidence confirms a finalized root's payments in one read through Multicall3, with SigvaraVerifier.verifyEvidenceMany, so a long payment history no longer fails against a public RPC. New since 1.0.0-alpha.16: evidenceLeaf, matchEvidenceRoot and sigvara_verify_evidence read a payment that settled on a payment chain. New since 1.0.0-alpha.15: SigvaraTrustCheck, which asks the gate's question about a bare address, with no proof; sigvaraX402Fetch, which checks the seller before an x402 payment is signed; sigvaraTrustTool and requireTrustedAgent, for LangChain and its like; minBond on SigvaraGate, with its below_bond refusal; challengeSecret on SigvaraGate, which accepts only challenges the gate issued, with generateChallenge taking an optional fourth argument that makes the nonce; a spent nonce recorded for one agent and one audience, as a hash a NonceStore is handed where it was handed the nonce; and SigvaraVerifier keeping to 20 calls in a batch. New since 1.0.0-alpha.14: sigvara-mcp, a read-only MCP trust server for an agent's MCP host (see MCP Gated Tools), the evidence-root functions evidenceLeaf, evidenceRoot and matchEvidenceRoot, and reads on SigvaraVerifier for a trust check, verifyEvidence and getEvidenceRoot among them. Any framework that can start a local MCP server over stdio can use sigvara-mcp as it is, with no Sigvara-specific code. New since 1.0.0-alpha.13: profile: 'production' on SigvaraGate, which makes the constructor refuse to build the gate until instances and maxScoreAgeSeconds are both set. New since 1.0.0-alpha.12: atomicNonceStore; the gate's instances setting, with which a gate set to 'multiple' refuses to start without a nonce store with an atomic consume(); and signPaymentOutcome and verifyPaymentOutcome, which sign and check a payer's statement of whether one payment's work was delivered. New since 1.0.0-alpha.11: the agent's signChallenge is removed, so a call does not compile in TypeScript and throws in JavaScript, and signChallengeFor is the way to sign. New since 1.0.0-alpha.10: verifySignature requires the expected audience (see the changelog). SigvaraAgent.signChallengeFor, the read timeout, the parallel status and score read, the gate's bond check and optional maxScoreAgeSeconds limit, and the other items listed for 1.0.0-alpha.10 in the changelog are new since 1.0.0-alpha.9.
Section sources
At a high level, the repository provides:
- A TypeScript SDK exposing identity, verification, gating, challenges, and types
- Example MCP server demonstrating a reputation-gated tool
- Oracle service computing and serving reputation data
- Documentation describing the reputation model and framework integration patterns
graph TB
subgraph "SDK"
IDX["index.ts"]
AGT["agent.ts"]
VER["verifier.ts"]
GAT["gate.ts"]
CHA["challenge.ts"]
TYP["types.ts"]
end
subgraph "Examples"
MCP["server.mjs"]
end
subgraph "Oracle"
ORA["index.js"]
end
subgraph "Docs"
AF["ai-frameworks.md"]
RM["reputation-model.md"]
end
IDX --> AGT
IDX --> VER
IDX --> GAT
IDX --> CHA
IDX --> TYP
MCP --> GAT
MCP --> VER
ORA --> RM
AF --> IDX
AF --> VER
Diagram sources
- index.ts:1-72
- agent.ts
- verifier.ts
- gate.ts
- challenge.ts
- types.ts
- server.mjs:1-204
- index.js:1-1980
- ai-frameworks.md
- reputation-model.md
Section sources
The SDK exposes cohesive primitives for building reputation-aware agents:
- Identity and signing:
SigvaraAgentgenerates keys, derives DIDs, and signs challenges.signChallengeFor(payload, audience)signs only a challenge addressed to the audience the caller names. The agent'ssignChallenge(payload), which signed whatever it was handed, is removed in 1.0.0-alpha.12 (alpha.9 has onlysignChallenge) - Verification:
SigvaraVerifierreads on-chain identity and reputation, verifies signatures, and checks thresholds - Gating:
SigvaraGateissues nonces, enforces replay protection, validates proofs, and admits/refuses based on status and score - Checking an address:
SigvaraTrustCheckasks the gate's question about a bare address, with no proof.sigvaraTrustToolandrequireTrustedAgentput it in a framework's tools, andsigvaraX402Fetchputs it under an x402 client - Challenge protocol:
generateChallenge,signChallenge,verifyChallenge, payload parsing, and expiry checks - Types: shared interfaces for contracts, statuses, reputation data, challenges, and verifier configuration
Key responsibilities:
-
SigvaraAgent: deterministic DID derivation, Ed25519 key management, challenge issuance/signing -
SigvaraVerifier: RPC provider, contract wrappers, signature verification, reputation queries -
SigvaraGate: nonce store abstraction, audience binding, admission logic with clear refusal reasons -
challenge.*: v1/v2 payloads, base58 signatures, expiration semantics -
types.*: contract addresses, agent status, reputation fields, challenge structures
Section sources
The recommended architecture for reputation-aware AI agents:
- Agents generate a DID and sign challenges when challenged by peers or services
- Services gate access by verifying signatures and checking on-chain reputation thresholds
- Auditing is performed per action, typically fire-and-forget, to preserve critical-path performance
- Reputation is computed off-chain by the oracle and served via on-chain contracts
sequenceDiagram
participant Client as "AI Agent"
participant Service as "Gated Service"
participant Gate as "SigvaraGate"
participant Verifier as "SigvaraVerifier"
participant Chain as "On-chain Contracts"
Client->>Service : "tools/call restricted_search(did, query)"
Service->>Gate : "challenge(did)"
Gate-->>Service : "{payload, expiresAt, audience}"
Service-->>Client : "challenge response"
Client->>Client : "signChallengeFor(payload, audience)"
Client->>Service : "restricted_search(did, challenge, signature, query)"
Service->>Gate : "admit(did, challenge, signature)"
Gate->>Verifier : "verifySignature(...)"
Verifier->>Chain : "read identity + signature verify"
Verifier-->>Gate : "verified?"
Note over Gate,Verifier : status, bond and score are read together
Gate->>Verifier : "isActive(did) and hasMinimumStake(did)"
Verifier->>Chain : "read status and bond"
Verifier-->>Gate : "active and bonded?"
Gate->>Verifier : "getTotalScore(did)"
Verifier->>Chain : "read matured score"
Verifier-->>Gate : "score"
Gate-->>Service : "admit result (ok, reason, score)"
Service-->>Client : "work or refusal"
Diagram sources
classDiagram
class SigvaraAgent {
-keyPair
-_agentAddress
-_chainId
-_challengeTtl
+constructor(options)
+static generate(options)
+agentAddress
+did
+didHash
+publicKeyBytes32
+issueChallenge(peerDid, ttlSeconds)
+signChallengeFor(payload, audience)
}
class SigvaraVerifier {
-provider
-addresses
-_chainId
-_identity
-_reputation
-_staking
+constructor(config)
+getIdentity(did)
+isActive(did)
+getReputation(did)
+getTotalScore(did)
+getScoreUpdatedAt(did)
+meetsThreshold(did, threshold)
+getStake(did)
+hasMinimumStake(did)
+verifySignature(did, challengePayload, signatureBase58, maxAgeSeconds, expectedAudience)
+buildDidDocument(did)
}
class SigvaraGate {
-verifier
-nonces
-ttl
-inFlight
+threshold
+audience
+constructor(config)
+challenge(did)
+admit(did, challenge, signatureBase58)
}
class Challenge {
+payload
+nonce
+timestamp
+expiresAt
+audience
}
SigvaraGate --> SigvaraVerifier : "uses"
SigvaraAgent --> Challenge : "issues"
Diagram sources
Section sources
- Wrap tools so every call includes the agent DID and posts an audit event
- Use a verifier to enforce minimum reputation before executing sensitive tasks
- The Python examples are illustrative pseudocode; there is no Python SDK, and the
sigvarapackage they import does not exist. Production Python agents should call the oracle HTTP API directly or run the TypeScript SDK in a sidecar - The oracle's
/scoreis a preview, not the finalized score. To gate on a threshold, readgetTotalScoreormeetsThresholdfrom the reputation contract with a plaineth_call, which any language can make. Both read the matured score alone and ignore status and bond, so also checkisActiveandhasMinimumStake, or callSigvaraReader.isTrusted, on Arc testnet at0x2921b4eE879CdF5793FA273BbDc4E7dF01ABcef8, which takes the same plaineth_call(see sigvara.xyz/integrate)
Implementation guidance:
- Initialize
SigvaraAgentfrom environment variables - For each tool execution, post an audit event asynchronously
- Before running sensitive operations, check
meetsThresholdwith a policy-defined minimum score, together withisActiveandhasMinimumStake(meetsThresholdignores status and bond)
Section sources
From 1.0.0-alpha.16 the SDK has two pieces for LangChain and its like. You pass in LangChain's own tool, so LangChain does not become a dependency of the SDK. The real package was run against this release.
-
sigvaraTrustTool(tool, trust)makes a tool the model can call before dealing with another agent. It answers in JSON:ok, andreasonanddetailwhen it is false, so the model can say why it will not go ahead. -
requireTrustedAgent(fn, trust, agentFrom)makes a tool of yours refuse to act for an agent without standing, whatever the model decided.agentFromsays which agent a call is about. A refusal throwsUntrustedAgentError, whoseverdictsays why. A chain read that fails throws too, andfndoes not run.
requireTrustedAgent is the one to rely on. A model can be talked out of calling a check, and cannot be talked out of a refusal in the code it calls.
Both take a SigvaraTrustCheck, built from rpcUrl, addresses, chainId and minScore, with optional minBond, maxScoreAgeSeconds and timeoutMs. They check a 0x address, not who is on the other end: they say what the chain holds about that agent, and do not prove that the party you are talking to controls it. For that, use SigvaraGate.
To stop an agent paying a seller without standing over x402, put the check under its client: wrapFetchWithPayment(sigvaraX402Fetch(fetch, trust), client). See TypeScript SDK.
Section sources
- Extend the assistant to attach Sigvara identity and audit every reply
- Include connector ID, agent DID, and message metadata in audit events
- Keep auditing fire-and-forget to avoid blocking LLM generation
Section sources
- Attach Sigvara identity to crew members and audit task results via callbacks
- Ensure the callback posts audit events with task name and result preview
Section sources
- Use middleware to wrap async functions and emit audit events without blocking
- Implement challenge-response for agent-to-agent authentication: answer an inbound challenge with
signChallengeFor(payload, peerDid), wherepeerDidcomes from the connection and not from the payload, and verify an inbound agent withverifySignature(did, payload, signature, 300, myAgent.did)so that a relayed response fails (signChallengeForis in 1.0.0-alpha.10 and later) - Verify signatures and reputation thresholds before trusting peer output
flowchart TD
Start(["Start"]) --> Init["Initialize SigvaraAgent<br/>from private key and chain config"]
Init --> Wrap["Wrap async function with audit middleware"]
Wrap --> Call["Call wrapped function"]
Call --> Audit["Fire-and-forget audit POST"]
Audit --> Return(["Return result"])
Diagram sources
Section sources
The MCP example demonstrates a two-step handshake:
- Step 1: Request a challenge for the caller’s DID
- Step 2: Submit the signed challenge along with the requested operation
The server enforces:
- Signature verification against the registered public key
- Audience binding to prevent cross-service replay
- Nonce uniqueness to prevent replays
- Active status and maturity-based score threshold
sequenceDiagram
participant Host as "MCP Host"
participant Server as "Gated MCP Server"
participant Gate as "SigvaraGate"
participant Verifier as "SigvaraVerifier"
participant Chain as "On-chain Contracts"
Host->>Server : "tools/list"
Server-->>Host : "sigvara_challenge, restricted_search"
Host->>Server : "sigvara_challenge{ did }"
Server->>Gate : "challenge(did)"
Gate-->>Server : "{ payload, expiresAt, audience }"
Server-->>Host : "challenge object"
Host->>Host : "signChallengeFor(payload, audience)"
Host->>Server : "restricted_search{ did, challenge, signature, query }"
Server->>Gate : "admit(did, challenge, signature)"
Gate->>Verifier : "verifySignature(...)"
Verifier->>Chain : "read identity + verify"
Verifier-->>Gate : "verified?"
Note over Gate,Verifier : status, bond and score are read together
Gate->>Verifier : "isActive(did) and hasMinimumStake(did)"
Verifier->>Chain : "read status and bond"
Verifier-->>Gate : "active and bonded?"
Gate->>Verifier : "getTotalScore(did)"
Verifier->>Chain : "read matured score"
Verifier-->>Gate : "score"
Gate-->>Server : "admit result"
Server-->>Host : "admitted or refusal"
Diagram sources
Section sources
flowchart TD
Issue["Generate challenge<br/>(prover DID, audience, TTL)"] --> Sign["Sign payload with agent private key"]
Sign --> Submit["Submit (did, payload, signature)"]
Submit --> Parse["Parse payload and validate version"]
Parse --> Expire{"Expired?"}
Expire --> |Yes| Reject["Reject as bad proof"]
Expire --> |No| Verify["Verify signature against on-chain public key"]
Verify --> Valid{"Valid?"}
Valid --> |No| Reject
Valid --> CheckNonce["Check nonce uniqueness"]
CheckNonce --> NonceOK{"Nonce used?"}
NonceOK --> |Yes| Replay["Reject as replayed"]
NonceOK --> |No| Status["Check active status and bond"]
Status --> Active{"Active and bonded?"}
Active --> |No| NotActive["Reject as not active"]
Active --> Score["Read matured score"]
Score --> Bond{"Holds less than minBond? Only if minBond is set"}
Bond --> |Yes| BelowBond["Reject as below_bond"]
Bond --> |No| Fresh{"Too old? Only if maxScoreAgeSeconds is set"}
Fresh --> |Yes| Stale["Reject as stale_score"]
Fresh --> |No| Threshold{"Meets threshold?"}
Threshold --> |No| Below["Reject as below_threshold"]
Threshold --> |Yes| Admit["Admit"]
Diagram sources
Section sources
The SDK components have clear dependencies:
-
index.tsre-exports core classes and utilities -
SigvaraAgentdepends on cryptographic helpers and challenge generation -
SigvaraVerifierdepends on ethers RPC, ABIs, DID utilities, challenge verification, and key encoding -
SigvaraGatedepends onSigvaraVerifierand challenge utilities, plus a nonce store abstraction and the shared rule instanding.ts -
SigvaraTrustCheckdepends onSigvaraVerifier, andsigvaraTrustTool,requireTrustedAgentandsigvaraX402Fetchtake a trust check as an argument, so none of them adds a dependency - The MCP example depends on
SigvaraGateand environment configuration
graph LR
IDX["index.ts"] --> AGT["agent.ts"]
IDX --> VER["verifier.ts"]
IDX --> GAT["gate.ts"]
IDX --> STD["standing.ts"]
IDX --> TLS["tools.ts"]
IDX --> XFT["x402.ts"]
GAT --> STD
STD --> VER
IDX --> CHA["challenge.ts"]
IDX --> TYP["types.ts"]
GAT --> VER
GAT --> CHA
VER --> CHA
VER --> TYP
MCP["server.mjs"] --> GAT
MCP --> VER
Diagram sources
Section sources
Optimization strategies for high-frequency reputation checks:
- Use
getTotalScoreinstead of full reputation tuples when only the total matters - Let
SigvaraGateread the status, the bond and the score together, and keep the default 30 second read timeout or settimeoutMs, so a quiet RPC does not hold every admit for ethers' five minutes - Batch independent RPC calls using ethers’ built-in batching to reduce round trips.
SigvaraVerifierkeeps to 20 calls in a batch, because Arc's public RPC answers 20 and refuses the rest with a rate limit - Cache contract instances and chain IDs to avoid repeated initialization
- Prefer view calls and read-only operations for reputation checks
- Use fire-and-forget auditing to keep critical paths fast
- Employ a distributed nonce store for multi-instance deployments to prevent replays, and set
instances: 'multiple'onSigvaraGateso it refuses to start without one - Tune TTL and audience values to balance security and latency
Oracle-side optimizations include:
- Chunked epoch processing to avoid releasing too many RPC requests at once
- Concurrent reads within chunks to leverage JSON-RPC batching
- Payer score caching per epoch to reduce repeated chain reads
- Deterministic timekeeping using chain timestamps to ensure reproducibility
Section sources
Common issues and diagnostics:
- Bad proof: signature does not verify, wrong audience, or malformed payload, or, with
challengeSecret, a challenge the gate did not issue - Replayed: valid signature but nonce already consumed
- Not active: agent is unbonded (or bonded below the minimum stake in force now), suspended, or slashed
- Below bond: only with
minBond: the agent holds the protocol's minimum but less than the gate asks for - Stale score: only with
maxScoreAgeSeconds: the score was proposed longer ago than the limit, or never - Below threshold: agent proved itself but matured score is insufficient
-
UntrustedAgentErrororX402SellerRefused: the address has no standing by the check's rule, andverdictorrefusedsays why. A seller paid anywhere but the agent's registered address reads as having no standing
Debugging steps:
- Validate challenge payload format and version
- Confirm audience matches the service identifier
- Check nonce lifecycle and storage backend
- Inspect agent status and stake requirements
- Compare matured score vs earned score to understand threshold behavior
- Review oracle logs for epoch failures, payment scan errors, and divergence records
Environment and configuration checks:
- Ensure required environment variables are set for RPC, addresses, and credentials
- Verify chain ID consistency between SDK and oracle
- Confirm threshold settings align with policy goals
Section sources
Sigvara enables reputation-aware AI agents through a consistent SDK pattern:
- Establish deterministic identity and audit every action
- Authenticate counterparties with challenge-response and audience binding
- Enforce gates based on active status and matured reputation scores
- Optimize for performance with batching, caching, and fire-and-forget auditing
- Deploy with robust configuration, monitoring, and testing practices
These patterns apply uniformly across LangChain, AutoGen, CrewAI, and custom TypeScript/Node.js adapters, while the MCP example demonstrates a production-ready gated toolchain.
- LangChain/AutoGen/CrewAI (Python): use environment variables for agent seed, address, chain ID, and CounterAudit API key; call oracle HTTP endpoints directly if no Python SDK exists
- TypeScript/Node.js: initialize
SigvaraAgentwith private key, agent address, and chain ID; configureSigvaraVerifierandSigvaraGatewith RPC URL, contract addresses, threshold, and audience, andSigvaraTrustCheckwith RPC URL, contract addresses, chain ID and minimum score
Section sources
- Required oracle variables: RPC URL, oracle private key (or
ORACLE_PRIVATE_KEY_FILE), identity address, reputation address. A write token (ORACLE_ADMIN_TOKENor anORACLE_TOKEN_<NAME>) is required for any bind other than loopback, and the fee registry and external registry settings are optional - SDK variables: RPC URL, contract addresses, chain ID, threshold, audience
- MCP server variables: chain ID, threshold, audience, RPC URL
Section sources
- Six-factor deterministic score: fee activity, success rate, tenure, external trust, community, propagation
- Maturity controls spendable score growth
- Bonding requirement before scoring
- Slashing resets all factors and marks agent terminal
Section sources
- Agent Registration and Lifecycle
- Contract Overview and Architecture
- Economic Security Model and Incentives
- Evidence Verification and Merkle Proofs
- Key Management and Rotation
- Maturity Mechanism and Score Release
- Proposal Workflow and Challenge System
- Score Storage and Data Model
- SigvaraIdentity Contract
- SigvaraOracleBond Contract
- SigvaraReputation Contract
- SigvaraStaking Contract
- Slashing Lifecycle and Dispute Resolution
- Stake Management Functions
- Status Management and Control
- Token and Fee Contracts
- Unbonding Period and Withdrawal Security
- Anti-Manipulation and Security Measures
- Community Flag Processing
- Evidence Sources and Verification
- External Trust Integration
- Merkle Proof System
- Oracle Score Computation
- Payment-Backed Attestations
- Scoring Model and Formulas
- Agent Creation and Key Management
- Agent Operations
- Agent Registration Workflow
- Challenge-Response Authentication
- Gate Access Control
- Integration Patterns and Examples
- SDK Overview and Setup
- Verifier Functions