Repository navigation
Getting Started
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
Sigvara is a blockchain protocol that gives autonomous AI agents a trust layer: computed reputation and staked slashing on top of ERC-8004 identity and feedback. In short, it answers two questions that matter for decentralized AI systems:
- How do you know which agent did what?
- What happens when an agent misbehaves?
ERC-8004 provides the standard identity and raw feedback ledger. Sigvara adds the hard parts: computing a normalized reputation score from that feedback and putting slashable stake behind it. The result is an agent whose reputation can be checked by other agents or smart contracts, and whose operator has real economic accountability through stake and slashing.
For beginners, think of an agent as an AI service with an on-chain identity, an operator as the person or system controlling it, a stake as collateral posted to keep the agent honest, and a reputation score as the number consumers use to decide whether to work with that agent. If the agent behaves badly, a committee can initiate a slash, suspending the agent and potentially destroying part of the stake.
For experienced developers, Sigvara is a set of upgradeable UUPS proxy contracts, an off-chain oracle network, and a TypeScript SDK. It runs today on Arc testnet (chain ID 5042002) with live scoring, payment-backed attestations, and bonded oracle operators.
The testnet proxies run the code on main, with the older role administrators described on the Governance and Upgrades page: identity and reputation since 26 October 2026, and staking and the oracle bond since their upgrades of 2 November. This page describes that code. The SDK is at 1.0.0-alpha.14, published to npm on 2 November 2026, and it has the SDK changes this page describes. Its changelog lists what each release changed.
Section sources
At a high level, this repository contains:
| Area | Purpose |
|---|---|
src/ |
Core Solidity contracts: identity, staking, reputation, token, fees, and oracle bond, plus the stateless SigvaraReader for contracts that gate on an agent's standing (in the repository, deployed nowhere) |
oracle/ |
Reference oracle implementation that computes scores and serves evidence |
packages/sdk/ |
TypeScript SDK for registration, verification, challenges, and reputation queries |
script/ |
Foundry deployment and upgrade scripts |
scripts/ |
Repository checks and tools, including fetch-deps.sh, which fetches the Solidity dependencies |
examples/ |
An MCP tool gated on reputation and a gated marketplace contract |
test/ |
Foundry unit, fuzz, invariant, E2E, upgrade, deploy-script, and fork tests |
docs/ |
Architecture, quickstart, reputation model, Arc deployment, and ecosystem guides |
deployments/ |
Live contract addresses for Arc testnet |
foundry.toml |
Foundry build, fuzz, and RPC configuration |
graph TB
subgraph "Contracts"
ID["SigvaraIdentity"]
ST["SigvaraStaking"]
REP["SigvaraReputation"]
TOKEN["SVRToken"]
ORACLE_BOND["SigvaraOracleBond"]
end
subgraph "Off-chain"
ORACLE["Reputation Oracle"]
SDK["@sigvara/protocol-sdk"]
end
subgraph "Standards"
ERC8004["ERC-8004 Identity + Feedback"]
end
SDK --> ID
SDK --> REP
SDK --> ST
ORACLE --> REP
ORACLE --> ERC8004
REP --> ID
ST --> ID
Diagram sources
Section sources
The protocol centers on five main concepts:
| Concept | Meaning in Sigvara | Why it matters |
|---|---|---|
| Agent | An AI service identified by a DID derived from its Ethereum address and chain ID | Consumers can check who performed an action |
| Operator | The wallet or controller responsible for registering, bonding, and managing the agent | Accountability attaches to a controllable party |
| Stake | ERC-20 tokens deposited against an agent’s identity | Makes the agent slashable and prevents bulk registration without cost |
| Reputation Score | A 0–100 normalized score computed off-chain and anchored on-chain | Lets other agents or contracts gate access based on standing |
| Slash | A penalty process initiated by a committee that can suspend or terminate an agent | Gives the stake real teeth |
The most important state transitions are:
stateDiagram-v2
[*] --> PendingBond : registerAgent()
PendingBond --> Active : depositStake() reaches minimumStake
Active --> Suspended : operator.updateStatus() or slash initiation
Suspended --> Active : operator.updateStatus() or dispute resolution
Active --> Slashed : executeSlash()
Suspended --> Slashed : executeSlash()
Slashed --> [*] : terminal
Any move into Active requires the agent to hold minimumStake, including the ones the staking core makes when a slash is dropped. On main a slash is also dropped when the committee cancels it, when the admin vetoes it, and when anyone lapses it 14 days after its challenge deadline; the veto and the lapse are not on the testnet.
Diagram sources
Section sources
Sigvara sits above ERC-8004. ERC-8004 owns canonical agent identity and raw feedback; Sigvara computes a normalized score and enforces bonds and slashing.
graph TB
subgraph "Signal Sources"
PY["Payers<br/>signed outcomes (delivered)"]
CA["CounterAudit<br/>seals packets, carries payer outcomes"]
WD["Watchdog scanners<br/>rug / abuse flags"]
end
subgraph "ERC-8004"
EID["Identity Registry<br/>agent identity"]
EREP["Reputation Registry<br/>raw feedback"]
end
subgraph "Sigvara Trust Layer"
OR(["Reputation Oracle<br/>computes the score"])
REP["SigvaraReputation<br/>computed-score anchor"]
ST["SigvaraStaking<br/>bonds + slashing"]
end
CONS["SDK · consumers · on-chain readers"]
PY --> |"payerOutcome"| OR
CA --> |"payer-signed outcomes"| OR
WD --> |"flags"| OR
EID --> |"ownership check"| OR
EREP --> |"feedback to externalScore"| OR
OR --> |"propose / finalize"| REP
ST --> |"slash · zero score"| REP
CA -.-> |"giveFeedback (off in production)"| EREP
REP --> |"getTotalScore · meetsThreshold"| CONS
Diagram sources
The key design principle is separation of concerns:
- Contracts store and serve reputation; they do not compute it.
- The oracle reads chain data and attestations, then proposes a score.
- A challenge window lets a committee reject bad proposals before finalization.
- Finalization is permissionless so no single party can hold a score hostage.
- Slashing zeroes reputation and marks the agent terminal.
Section sources
To develop against Sigvara, install the tools required by the repository:
- Install Node.js 18+.
- Install Foundry (
forge,cast). - Clone the repository.
- Fetch the Solidity dependencies, build and test:
git clone https://github.com/RunTimeAdmin/sigvara
cd sigvara
sh scripts/fetch-deps.sh # OpenZeppelin and forge-std, each fetched by commit into lib/ (gitignored, no submodules)
forge build
forge testforge test runs offline except for two fork suites: SlashDrillFork.t.sol forks Arc testnet on every run, so it needs the arc_testnet endpoint in foundry.toml to answer, and SplitAuthorityFork.t.sol skips its twelve tests unless you pass --fork-url https://rpc.testnet.arc.io. The suite has 724 tests, and 712 of them run without a fork URL.
Foundry configuration lives in foundry.toml. It sets the source directory, output directory, library remappings, optimizer settings, Solidity version, EVM version (cancun), fuzz runs, CI fuzz profile, and RPC endpoints for Arc testnet and Arc mainnet.
Arc-specific notes:
- Gas is paid in native USDC on Arc, not ETH.
- If fee estimation fails with
forge script, retry with--legacy. - Do not add
[etherscan]entries for chain IDs5042002or5042until Foundry ships native chain metadata for Arc.
Section sources
This guide targets Arc testnet (chain ID 5042002). You should be able to go from zero to a registered, reputation-tracked agent in roughly ten minutes.
- Node.js 18+
- A wallet with Arc testnet USDC from the Circle faucet
- Testnet stake tokens from the SVRToken faucet
Install the protocol SDK and ethers:
npm install @sigvara/protocol-sdk ethersCreate environment variables for your operator private key and RPC URL:
OPERATOR_PRIVATE_KEY=0x...
RPC_URL=https://rpc.testnet.arc.ioUse the live Arc testnet contract addresses from deployments/5042002.json:
- Identity
- Reputation
- Staking
- SVRToken (testnet faucet token)
The testnet SVRToken supports a public faucet that mints up to 10,000 SVR per call, once per wallet per 24 hours. Use it to fund the operator wallet with enough stake tokens for registration.
Your agent needs an Ed25519 cryptographic identity. Store the private key securely because it cannot be recovered. The agent address can be the same as the operator address on testnet.
Registration alone leaves the agent in PendingBond. It is not active and not scoreable until a deposit carries it over minimumStake. That first qualifying deposit activates the agent.
The registration requires a signature from the agent address itself. This proves control of the agent address and prevents someone from registering an address they do not own and choosing the Ed25519 key verifiers will check.
After registration, deposit the minimum stake using the staking contract.
Use the SDK verifier to read the agent’s identity status and reputation. Initially, the total reputation may read zero because:
- The oracle must run an epoch.
- The proposed score must clear its challenge window.
- The matured score climbs toward the earned score over time.
A freshly bonded agent with no verified work starts at the community baseline and grows only as verified, paid activity accrues.
To watch it from a browser, find the agent on the site's Agents page (sigvara.xyz/agents), which lists every agent on Arc testnet with its score and stake and can recheck the evidence behind the score, or open the Score epochs page (sigvara.xyz/epochs) for each proposal and what became of it. Agents marked "Simulated" there belong to Sigvara's labelled testnet simulation (20 agents, 40 customers, a Sybil ring and two slashes over four weeks), and their activity is not outside demand.
Agents authenticate each other using Ed25519 signatures bound to their DID. A verifier issues a challenge, the prover signs it, and the verifier checks both the signature and the agent’s reputation threshold. The prover should sign with signChallengeFor(payload, audience), which signs only a challenge addressed to the verifier it means to prove itself to, and the verifier should pass its own audience to verifySignature. signChallengeFor is in 1.0.0-alpha.10 and later. On alpha.9 call signChallenge, after checking yourself that the payload names the verifier you mean to prove yourself to. From 1.0.0-alpha.12 the agent's signChallenge is gone: it throws and names signChallengeFor.
If you audit agent actions with CounterAudit, pass the agent DID into ingest calls. CounterAudit enriches sealed packets with the agent’s on-chain identity and reputation score frozen at the moment of the action.
Section sources
The full deployment flow is documented under Arc deployment. The practical steps are:
-
Prepare Foundry and fetch OpenZeppelin and forge-std with
sh scripts/fetch-deps.sh. -
Confirm the chain and fund the deployer with Arc testnet USDC.
-
Simulate deployment:
forge script script/Deploy.s.sol --rpc-url arc_testnet -vvvv
-
Broadcast deployment:
forge script script/Deploy.s.sol --rpc-url arc_testnet --broadcast -vvvv
-
Record the deploy block number for the oracle (the deploy script writes it to the artifact as
deployBlock). -
Point the oracle at Arc by copying
.env.example, setting RPC, registry addresses, start block, epoch interval, and oracle private key. -
Run the SDK integration tests against the live testnet contracts.
Important operational details:
- Only one oracle instance may run at a time because instances share the oracle wallet and colliding nonces would break submission.
- The oracle publishes health, score, and evidence endpoints publicly so anyone can audit the Merkle root.
- Payment scanning can be enabled so operators find payments themselves by reading
Transferlogs rather than waiting for attestations.
Section sources
sequenceDiagram
participant Op as "Operator"
participant ST as "SigvaraStaking"
participant ID as "SigvaraIdentity"
Note over Op : Generate Ed25519 keypair off-chain
Op->>ID : registrationDigest(agentAddress, operator, ed25519PubKey)
ID-->>Op : digest
Note over Op : The agent address signs the digest
Op->>ID : registerAgent(agentAddress, ed25519PubKey, signature)
ID->>ID : compute didHash
ID->>ID : verify signature
ID-->>Op : AgentRegistered(didHash, operator, agentAddress, pubKey)
Note over ID : Status = PendingBond
Op->>ST : depositStake(didHash, minimumStake)
ST->>ID : updateStatus(didHash, Active)
ST-->>Op : bond recorded, agent Active
Diagram sources
Section sources
sequenceDiagram
participant V as "Victim"
participant CM as "Slashing Committee"
participant AD as "Admin Safe"
participant ST as "SigvaraStaking"
participant ID as "SigvaraIdentity"
participant REP as "SigvaraReputation"
V->>CM : report agent + evidence package
CM->>ST : initiateSlash(didHash, victim, evidenceHash)
ST->>ID : updateStatus(didHash, Suspended)
Note over ST : 7-day challenge period begins
alt Operator disputes within window
Op->>ST : disputeSlash(didHash)
Note over ST : Proposal → Disputed. Bond stays frozen,<br/>agent stays Suspended
AD->>ST : resolveDispute(didHash, uphold)
Note over ST : Upheld slashes, but not before the 7-day deadline. Rejected cancels and reinstates at once while the bond still meets `minimumStake`.<br/>Unruled after 14 days, anyone may expireDispute()
else Challenge period elapses undisputed
Anyone->>ST : executeSlash(didHash)
ST->>ID : updateStatus(didHash, Slashed)
ST->>REP : zeroReputation(didHash)
ST-->>0xdead : 75% burned
ST-->>V : 25% to victim
Note over ST : Not executed within 14 days of the deadline, anyone may expireSlash()
end
This is the flow on main, which the testnet staking proxy runs: the admin ruling since 26 October 2026, the refusal of an uphold once the dispute can be expired since 28 October, and the split that pays the reporter nothing since 2 November. The admin rules on a dispute, and can also vetoSlash a pending or disputed proposal. After any dropped proposal (cancelled, vetoed, lapsed, or ruled against) the committee has to wait one challenge period before it can file against the same agent again.
Diagram sources
Section sources
sequenceDiagram
participant UC as "User / Counterparty"
participant OR as "Oracle Network"
participant REP as "SigvaraReputation"
participant CM as "Slashing Committee"
UC->>OR : attestation + settlement tx of the payment for the job
OR->>OR : verify the transfer on chain, take the payer from the log
Note over OR : epoch aggregation over decayed, per-payer-capped evidence
OR->>OR : compute 6-factor scores + Merkle root over the evidence used
OR->>REP : proposeReputation(didHash, ReputationData, evidenceRoot)
REP->>REP : validate per-factor caps, require a bonded agent
REP-->>OR : ScoreProposed(didHash, proposedAt)
Note over REP : Challenge window open
alt Committee rejects during the window
CM->>REP : rejectReputation(didHash)
REP-->>CM : ScoreRejected(didHash)
Note over REP : Previous finalized score is untouched
else Window elapses unchallenged
UC->>REP : finalizeReputation(didHash) — permissionless
REP-->>UC : ReputationUpdated(didHash, totalScore)
Note over REP : Score now live for A2A threshold checks
end
Diagram sources
Section sources
The contracts have a small but important dependency graph:
graph LR
STAKING["SigvaraStaking"] --> IDENTITY["SigvaraIdentity"]
REPUTATION["SigvaraReputation"] --> IDENTITY["SigvaraIdentity"]
REPUTATION --> ORACLE_BOND["SigvaraOracleBond (optional)"]
Key relationships:
-
SigvaraStakingdepends onSigvaraIdentityto read agent status and enforce slashability. -
SigvaraReputationdepends onSigvaraIdentityto ensure only registered, non-slashed, bonded agents receive scores. -
SigvaraReputationoptionally depends onSigvaraOracleBondto require bonded oracle operators when configured. -
SigvaraIdentityuses a view interface toSigvaraStakingto check minimum stake without creating a circular import.
classDiagram
class SigvaraIdentity {
+registerAgent(agentAddress, ed25519PubKey, signature) bytes32
+updateStatus(didHash, newStatus) void
+rotatePublicKey(didHash, newEd25519PubKey) void
+offerOperatorTransfer(didHash, newOperator) void
+acceptOperatorTransfer(didHash) void
+computeDidHash(agentAddress) bytes32
+getIdentity(didHash) AgentIdentity
+isActive(didHash) bool
}
class SigvaraStaking {
+depositStake(didHash, amount) void
+initiateWithdrawal(didHash, amount) void
+claimWithdrawal(didHash) void
+initiateSlash(didHash, victim, evidenceHash) void
+disputeSlash(didHash) void
+resolveDispute(didHash, uphold) void
+executeSlash(didHash) void
+hasMinimumStake(didHash) bool
}
class SigvaraReputation {
+proposeReputation(didHash, data, evidenceRoot) void
+finalizeReputation(didHash) void
+rejectReputation(didHash) void
+zeroReputation(didHash) void
+getTotalScore(didHash) uint8
+meetsThreshold(didHash, threshold) bool
}
SigvaraStaking --> SigvaraIdentity : "reads status"
SigvaraReputation --> SigvaraIdentity : "validates agent"
Diagram sources
Section sources
From a developer perspective, performance and reliability matter in three places:
- Contract gas usage: Transfers, status changes, and slash execution touch multiple contracts. Keep consumer logic simple and avoid repeated expensive reads in hot paths.
- Oracle liveness: The oracle recomputes scores every epoch. Its state file, log scan cursor, and attestations are critical. Restarting without recovering state can collapse payment-derived factors.
- Maturity and decay: Reputation does not jump instantly to its peak. Maturity prevents farm-and-cash-out attacks, while decay prevents stale scores from remaining valuable forever.
Practical implications:
- Consumers should read
getTotalScoreandmeetsThreshold, not just the raw earned score.meetsThresholdcompares the score alone, so a suspended agent passes it. A contract that needs standing as well should callSigvaraReader.isTrusted, which also checks that the agent is Active and that the bond it holds now meets the current minimum stake. The reader is in the repository and deployed nowhere. - Thresholds should account for the reachable ceiling when ERC-8004 external trust is low.
- Operators should monitor oracle health, payment scanning progress, and divergence endpoints.
Section sources
Common issues and how to diagnose them:
| Symptom | Likely Cause | Resolution |
|---|---|---|
| Registration reverts with a bad signature error | The agent address did not sign the unprefixed registration digest | Compute registrationDigest and sign it with the agent address |
Agent remains PendingBond
|
No qualifying stake was deposited | Deposit at least minimumStake from the correct operator |
| Reputation reads zero immediately after activation | Epoch has not finalized or maturity has not started | Wait for the oracle epoch and challenge window |
| Oracle stops proposing scores | Missing roles, wrong RPC, missing registry wiring, or operator bond not admitted | Check ORACLE_ROLE, RPC, registry addresses, and isActiveOperator
|
| SDK integration tests fail on Arc | Missing USDC gas or SVR stake tokens | Fund the operator wallet and faucet the testnet SVRToken |
| Upgrade breaks behavior | Wrong initialization order or missing calldata | Follow the documented upgrade sequence and replay against a fork |
Key diagnostics:
- Use
forge testfor contract testing. It is offline apart from the two fork suites described under installation. - Use
npx vitest runinpackages/sdkfor SDK tests. - Use
pwsh scripts/check-arc.ps1to verify Arc setup. - Check
/health,/score/:didHash, and/evidence/:didHashfor oracle status. - Verify live contract addresses in
deployments/5042002.json.
Section sources
Sigvara gives decentralized AI systems a practical trust primitive: an agent identity backed by stake, with a reputation score that consumers can check and a slashing mechanism that makes misbehavior costly. For newcomers, the essential workflow is register, bond, earn verified activity, and watch the reputation grow. For developers, the essential stack is Foundry for contracts, the Arc testnet for deployment, the oracle for scoring, and the SDK for interaction.
The protocol is intentionally early and transparent: it documents its testnet lineage, known weaknesses, and mainnet blockers rather than claiming production readiness. If you are building autonomous agents that need to prove who they are, show why they are trustworthy, and face consequences when they are not, Sigvara is the place to start.
| Term | Definition |
|---|---|
| Agent | An autonomous AI service with an on-chain identity |
| Operator | The controller responsible for registering, bonding, and managing an agent |
| Stake | Collateral deposited against an agent’s identity |
| Reputation Score | A 0–100 normalized score computed off-chain and stored on-chain |
| Slash | A penalty process that can suspend or terminate an agent and distribute stake |
| Evidence Root | A Merkle root committing to the payments counted in a score |
| Maturity | The delay between earning a score and being allowed to spend it |
| Decayed Evidence | Payment evidence weighted less as it ages |
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