Skip to content

SDK Overview and Setup

RunTimeAdmin edited this page Nov 3, 2026 · 34 revisions

SDK Overview & Setup

**Referenced Files in This Document** - [README.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/README.md) - [quickstart.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/docs/quickstart.md) - [package.json](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/package.json) - [SDK README.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/README.md) - [index.ts](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/src/index.ts) - [agent.ts](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/src/agent.ts) - [verifier.ts](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/src/verifier.ts) - [gate.ts](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/src/gate.ts) - [types.ts](https://github.com/RunTimeAdmin/Sigvara/blob/main/packages/sdk/src/types.ts)

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

Introduction

This document explains the Sigvara TypeScript SDK, its purpose, installation, configuration, and core concepts for interacting with the Sigvara protocol smart contracts. The SDK provides:

  • Agent identity management using did:sigvara identifiers and Ed25519 keys
  • Cryptographic challenge-response authentication between agents
  • On-chain reads for identity, reputation, stake, and threshold checks
  • A gate that turns identity verification and reputation into a single admission decision

The repository also documents the broader protocol: ERC-8004-based agent identity, computed reputation, staked accountability, slashing, and an oracle-driven scoring system.

This page describes the SDK in 1.0.0-alpha.15, published to npm on 3 November 2026. 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. 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). These items are new since 1.0.0-alpha.9 (listed in the changelog): signChallengeFor, the 30 second read timeout, the parallel status and score read, the gate also checking the bond held now, the optional maxScoreAgeSeconds limit and its stale_score refusal, the refusal of a challenge dated in the future, the checks on a gate's threshold, ttlSeconds and maxScoreAgeSeconds, and the agent keeping its secret key in a private field.

Section sources

Project Structure

At a high level, the SDK lives under packages/sdk. Its public API is re-exported from the package entry point, while domain modules implement agent identity, verification, gating, challenges, DID helpers, key utilities, types, and contract interaction.

graph TB
Entry["packages/sdk/src/index.ts<br/>Public exports"] --> Agent["agent.ts<br/>Agent identity + signing"]
Entry --> Verifier["verifier.ts<br/>On-chain reads + registration"]
Entry --> Gate["gate.ts<br/>Admission decision"]
Entry --> Types["types.ts<br/>Shared types"]
Verifier --> Abis["abis.ts (ABI bindings)"]
Verifier --> Did["did.ts (DID helpers)"]
Verifier --> Challenge["challenge.ts (payload handling)"]
Verifier --> Keys["keys.ts (key encoding)"]
Loading

Diagram sources

Section sources

Core Components

  • Agent: Generates and holds an Ed25519 keypair, derives the agent’s DID and on-chain didHash, signs challenges, and exposes the bytes32 public key used during registration.
  • Verifier: Connects to an RPC provider, reads identity and reputation data, verifies signatures against on-chain public keys, builds W3C-compliant DID Documents, and registers agents when called by an operator.
  • Gate: Issues signed challenges, enforces nonce replay protection, validates proofs before it reads status or score (checking a proof costs one read of the agent's registered key), checks agent status and the bond held now, compares the matured score against a threshold (and, if you set a limit, how old it is), and returns a structured result with a reason code.
  • Types: Shared interfaces for contract addresses, agent identity, reputation data, challenge payloads, verifier configuration, and DID documents.

Key responsibilities:

  • Identity: SigvaraAgent and DID helpers
  • Authentication: challenge generation, signing, and verification
  • Reputation: reading factors, total score, and threshold checks
  • Stake: deposit helper for moving an agent from pending to active
  • Gating: end-to-end admission logic with replay protection

Section sources

Architecture Overview

The SDK sits between your application and the Sigvara protocol contracts. It does not compute reputation itself; it reads on-chain state and performs local cryptographic operations. The one exception is sigvara-mcp's sigvara_verify_evidence, which also fetches an oracle's public /evidence list to check it against the chain.

graph TB
App["Your Application"] --> SDK["@sigvara/protocol-sdk"]
SDK --> Provider["ethers JsonRpcProvider"]
Provider --> RPC["RPC Endpoint"]
RPC --> Contracts
subgraph Contracts["Sigvara Contracts"]
Identity["SigvaraIdentity"]
Reputation["SigvaraReputation"]
Staking["SigvaraStaking"]
end
SDK --> Identity
SDK --> Reputation
SDK --> Staking
Loading

Diagram sources

Detailed Component Analysis

Installation and Package Details

  • Install via npm or yarn:
    • npm install @sigvara/protocol-sdk
    • yarn add @sigvara/protocol-sdk
  • Runtime dependencies:
    • ethers v6
    • tweetnacl
  • Node.js requirement:
    • Node 18 or newer

For web applications, you can bundle the SDK with your frontend toolchain. There is no separate CDN distribution declared in the package metadata; include it as a normal npm dependency and let your bundler resolve it.

Section sources

Environment Requirements

  • Node.js: 18+
  • Browser support: depends on your bundler and polyfills. The SDK builds as CommonJS and imports Node's crypto for random bytes (challenge.ts), so a browser bundle needs a crypto shim or fallback as well as ethers and tweetnacl.
  • Network access: required for RPC calls unless you are only performing local cryptographic operations.

Section sources

Basic Configuration

You need three things:

  • RPC endpoint URL
  • Contract addresses for identity, reputation, and staking
  • Chain ID

Example environment variables commonly used in quickstart guides:

  • RPC_URL=https://rpc.testnet.arc.io
  • Testnet contract addresses for Arc testnet chain ID 5042002

These values are passed into SigvaraVerifier and SigvaraGate configuration objects. Both also take an optional timeoutMs, a positive number of milliseconds that one chain read may take before it is abandoned. It defaults to 30000 (alpha.9 uses ethers' own default, which is five minutes).

Section sources

Module Import Patterns

The SDK exposes:

  • Classes: SigvaraAgent, SigvaraVerifier, SigvaraGate
  • Functions: registerAgent, depositStake, atomicNonceStore, generateChallenge, signChallenge, verifyChallenge, parseChallengePayload, isChallengeExpired
  • Payment outcomes (from 1.0.0-alpha.13): signPaymentOutcome, verifyPaymentOutcome and paymentOutcomeDomain, the constants PAYMENT_OUTCOME_TYPES, OUTCOME_DELIVERED, OUTCOME_NOT_DELIVERED and MAX_OUTCOME_DEADLINE_SECONDS, and their types
  • DID helpers: computeDidHash, formatDid, parseDid
  • Key utilities: base58/hex conversion, seed/keypair helpers, bytes32/public-key conversions
  • Evidence roots (from 1.0.0-alpha.15): evidenceLeaf, evidenceLayers, evidenceRoot, evidenceProof, matchEvidenceRoot and outcomeCode
  • Types: ContractAddresses, AgentIdentity, ReputationData, Challenge, ParsedChallenge, VerifierConfig, DidDocument, VerificationMethod, AgentStatus, and from 1.0.0-alpha.15 SlashState, PendingScore, PendingWithdrawal, SlashProposal, EvidenceRecord and RootMatch

Import from the package root rather than internal files. The exception is the trust server: createTrustServer and serveStdio are only in @sigvara/protocol-sdk/dist/mcp, kept out of the main entry because they use Node's readline. The two newer constants, MAX_FUTURE_SKEW_SECONDS (60, in challenge.ts) and DEFAULT_RPC_TIMEOUT_MS (30000, in verifier.ts), are exported from their modules but not re-exported from the package root.

Section sources

Agent Identity Management

An agent has:

  • An Ethereum address used as part of the DID
  • An Ed25519 keypair generated off-chain
  • A DID string: did:sigvara:<chainId>:<address>
  • A didHash derived on-chain at registration

Use SigvaraAgent.generate to create a new agent, then register it on-chain with an operator wallet. The agent must prove control of its Ethereum address during registration.

flowchart TD
Start(["Create Agent"]) --> Generate["Generate Ed25519 keypair"]
Generate --> DID["Derive did:sigvara DID"]
DID --> Hash["Compute didHash"]
Hash --> Register["Operator calls registerAgent()"]
Register --> Pending["Agent becomes PendingBond"]
Pending --> Stake["Deposit stake >= minimumStake"]
Stake --> Active["Agent becomes Active"]
Loading

Diagram sources

Section sources

Cryptographic Operations

The SDK handles:

  • Ed25519 keypair generation
  • Signing challenge payloads
  • Verifying signatures against on-chain public keys
  • Converting between hex, bytes32, base58, and multibase representations

Challenge-response flow:

  1. Verifier issues a challenge payload bound to the prover’s DID and an audience.
  2. Prover signs the payload with its Ed25519 private key. signChallengeFor(payload, audience) does this only if the payload is a v2 challenge naming the prover and exactly the audience the prover passes, and otherwise throws and signs nothing. The agent's signChallenge(payload) signed whatever it was handed and is removed in 1.0.0-alpha.12 (alpha.9 has only signChallenge, so on alpha.9 check the audience yourself before you sign).
  3. Verifier resolves the public key from the identity contract and verifies the signature.
  4. Verifier may additionally check reputation thresholds.
sequenceDiagram
participant V as "Verifier"
participant A as "Agent"
participant I as "Identity Contract"
participant R as "Reputation Contract"
V->>A : Issue challenge payload
A->>A : Sign payload with Ed25519 key
A-->>V : Return signature
V->>I : Resolve public key
I-->>V : Public key
V->>V : Verify signature
V->>R : Check meetsThreshold()
R-->>V : Boolean
Loading

Diagram sources

Section sources

Reputation System Interaction

The SDK reads:

  • Raw six-factor reputation data
  • Matured total score
  • Threshold checks
  • Stake and minimum-stake information

Important distinction:

  • Earned score: what the oracle finalized
  • Total score: the matured score used by meetsThreshold

Use getTotalScore when you only need the number compared against a threshold. Use getReputation when you need factor breakdowns.

Section sources

Gate: Admission Decision

SigvaraGate combines identity proof, replay protection, status checks, and reputation into one decision. It returns:

  • ok: whether the agent is admitted
  • reason: one of bad_proof, replayed, not_active, stale_score (only when maxScoreAgeSeconds is set), below_threshold
  • score: the agent’s on-chain score when available
  • threshold: the configured threshold
  • did: the agent’s DID

Nonce handling:

  • Default store is per process
  • For multiple instances, provide a shared NonceStore with atomic consume semantics and set instances: 'multiple', which refuses to start the gate without one. atomicNonceStore(setIfAbsent) builds such a store from any atomic insert-if-absent, such as a Redis SET NX (both from 1.0.0-alpha.13)

Construction and reads (new in 1.0.0-alpha.10):

  • new SigvaraGate(...) throws when threshold is not a finite number of 0 or more, or ttlSeconds or maxScoreAgeSeconds is not a positive number. A NaN threshold, such as Number(process.env.X) with X unset, would otherwise admit every active agent that can prove its key
  • The status, the bond held now and the score are read together once the proof and the nonce have passed, so an admit costs two round trips and not three. Standing is still named before score. An agent whose bond is under the minimum in force now is refused as not_active
  • maxScoreAgeSeconds (optional, off by default) refuses a score written longer ago than that, or never, as stale_score, after standing and before the number. It costs one more read per admit

Deployment settings:

  • instances (from 1.0.0-alpha.13) says how many processes serve the gate. It defaults to 'single'; 'multiple' makes the constructor throw unless the nonceStore has a consume(), which must be atomic and shared by every instance
  • profile: 'production' (from 1.0.0-alpha.14) makes the constructor throw until instances and maxScoreAgeSeconds are both set, and names everything missing in one error. Any other profile value throws too, so 'prod' read from an environment variable does not build an unchecked gate
flowchart TD
Start(["admit(did, challenge, signature)"]) --> Parse["Parse signed payload"]
Parse --> Verify["Verify signature + audience + expiry"]
Verify --> |Invalid| BadProof["Return bad_proof"]
Verify --> Nonce["Check nonce uniqueness"]
Nonce --> |Seen| Replayed["Return replayed"]
Nonce --> Status["Check isActive() and hasMinimumStake()"]
Status --> |False| NotActive["Return not_active"]
Status --> Score["Read getTotalScore()"]
Score --> Fresh{"Score too old? Only if maxScoreAgeSeconds is set"}
Fresh --> |Yes| Stale["Return stale_score"]
Fresh --> |No| Threshold{"Score >= threshold?"}
Threshold --> |No| Below["Return below_threshold"]
Threshold --> |Yes| Admit["Return ok=true"]
Loading

Diagram sources

Section sources

Step-by-Step Setup Instructions

Node.js

  1. Install the SDK and ethers:
    • npm install @sigvara/protocol-sdk ethers
  2. Configure environment variables:
    • OPERATOR_PRIVATE_KEY
    • RPC_URL=https://rpc.testnet.arc.io
  3. Set testnet contract addresses for chain ID 5042002.
  4. Generate an Ed25519 keypair with SigvaraAgent.generate.
  5. Register the agent with registerAgent.
  6. Deposit stake with depositStake to move the agent from PendingBond to Active.
  7. Read identity and reputation with SigvaraVerifier.

Section sources

Browser

  1. Add @sigvara/protocol-sdk to your project dependencies.
  2. Configure an RPC endpoint and contract addresses in your app settings.
  3. Use SigvaraAgent for client-side signing if your agent runs in the browser.
  4. Use SigvaraVerifier or SigvaraGate on the server side for secure verification and reputation checks.
  5. If running verification in the browser, ensure your bundler supports ethers and tweetnacl and provides a crypto module for Node's randomBytes.

Note: The package metadata does not declare a CDN entry point; treat it as a normal npm module.

Section sources

React Applications

  1. Install the SDK and ethers in your React project.
  2. Store RPC endpoints and contract addresses in environment variables.
  3. Create a verifier instance for on-chain reads.
  4. For agent-facing flows, generate and sign challenges in the browser using SigvaraAgent.
  5. For admission decisions, prefer server-side verification with SigvaraGate to keep nonces and secrets safe.
  6. If you need client-side gating, provide a distributed nonce store implementation through the NonceStore interface.

Section sources

Gas Optimization Settings

The SDK does not expose gas-specific configuration options. Gas behavior is controlled by:

  • Your signer/provider configuration
  • Contract-level parameters such as minimum stake and maturity
  • Transaction submission strategy in your application

Optimization tips:

  • Batch operations where possible
  • Cache contract instances and network info
  • Avoid unnecessary reads by using getTotalScore instead of full reputation tuples when only the threshold matters

Section sources

Common Setup Issues and Environment Requirements

  • Node.js version too old:
    • Requirement: Node 18+
  • Missing RPC endpoint:
    • Provide a valid RPC URL for the target network
  • Wrong contract addresses:
    • Use the addresses matching your selected chain ID
  • Using mainnet vs testnet incorrectly:
    • Arc testnet uses chain ID 5042002; mainnet configuration differs
  • Replay attacks:
    • Always use SigvaraGate or implement a shared nonce store with atomic consume
  • Audience mismatch:
    • Pass the same stable audience value to challenge generation and verification
  • Signature width or encoding errors:
    • The verifier rejects malformed signatures early; ensure clients send base58-encoded Ed25519 signatures within expected length bounds
  • A request that hangs on a dead RPC:
    • A read gives up after 30 seconds and timeoutMs changes that. On alpha.9 ethers waits five minutes

Section sources

Dependency Analysis

The SDK depends on:

  • ethers for RPC connectivity, contract interactions, and signing
  • tweetnacl for Ed25519 cryptography

Internal module relationships:

  • index.ts re-exports the public surface
  • agent.ts depends on key utilities, DID helpers, and challenge functions
  • verifier.ts depends on ABIs, DID helpers, challenge functions, key utilities, and types
  • gate.ts depends on verifier.ts and challenge functions
  • types.ts is consumed across modules
graph LR
Index["index.ts"] --> Agent["agent.ts"]
Index --> Verifier["verifier.ts"]
Index --> Gate["gate.ts"]
Agent --> Keys["keys.ts"]
Agent --> Did["did.ts"]
Agent --> Challenge["challenge.ts"]
Verifier --> Abis["abis.ts"]
Verifier --> Did
Verifier --> Challenge
Verifier --> Keys
Verifier --> Types["types.ts"]
Gate --> Verifier
Gate --> Challenge
Loading

Diagram sources

Section sources

Performance Considerations

  • Prefer getTotalScore when you only need the matured score for threshold checks.
  • Avoid reading the full reputation tuple unless you need factor breakdowns.
  • Use a shared nonce store with atomic consume in multi-instance deployments to avoid race conditions.
  • Cache provider and contract instances where appropriate.
  • Keep challenge TTLs reasonable to limit nonce storage growth.

Troubleshooting Guide

  • Registration fails because the agent did not sign:
    • Ensure the agent address signs the registration digest returned by the identity contract.
  • Agent remains PendingBond:
    • Deposit at least minimumStake to activate the agent.
  • Signature verification fails:
    • Confirm the payload names the correct DID and audience.
    • Confirm the signature is base58-encoded and within expected length bounds.
    • Confirm the challenge has not expired. A payload dated more than 60 seconds ahead of the verifier's clock is refused as well.
  • Gate returns replayed:
    • Issue a fresh challenge; do not reuse a previous response.
    • Implement a shared nonce store if running multiple instances, and set instances: 'multiple' so the gate refuses to start without one.
  • new SigvaraGate(...) throws:
    • Read the message. It names a threshold, ttlSeconds or maxScoreAgeSeconds that is not a usable number, an instances or profile value it does not accept, instances: 'multiple' with no consume() on the nonceStore, or, with profile: 'production', each setting still missing.
  • Gate returns not_active:
    • The agent is unbonded (or bonded below the minimum stake in force now), suspended, or slashed. Fix the standing issue before adjusting reputation.
  • Gate returns stale_score (only when maxScoreAgeSeconds is set):
    • The score was written longer ago than the limit, or never. Check that the oracle is running and finalizing; the number itself is not the problem.
  • Gate returns below_threshold:
    • Increase verified activity and reputation over time; the matured score climbs toward the earned score.

Section sources

Conclusion

The Sigvara TypeScript SDK is a focused client library for agent identity, cryptographic authentication, and reputation-aware admission decisions. Install it as a normal npm package, configure an RPC endpoint and contract addresses for your chosen network, and use the provided classes to manage agents, verify signatures, read reputation, and gate access. For production deployments, pay special attention to nonce replay protection, audience binding, and correct network configuration.

Overview

Clone this wiki locally