npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@katanga/sdk-verifier

v0.1.0

Published

Verifier-node SDK for the EP-710 dispute consensus engine on the Katanga marketplace.

Readme

@katanga/sdk-verifier

Verifier-node SDK for the EP-710 dispute consensus engine on the Katanga marketplace.

A verifier node:

  1. Watches KatangaDisputeConsensus.VotingPeriodStarted events.
  2. Fetches the buyer + supplier evidence URIs (off-chain, hash-verified against the on-chain commitment).
  3. Runs a pluggable adjudicator to decide the outcome (BUYER_WINS / SUPPLIER_WINS / SPLIT).
  4. EIP-712-signs a DisputeVote typed-data message and posts the signature to a permissionless aggregator.
  5. Anyone can then call KatangaDisputeConsensus.consensusFinalize(escrowId, result, signatures[]) once the threshold is met.

Install

pnpm add @katanga/sdk-verifier

The package is a workspace member; if you are inside this repo run:

pnpm install
pnpm --filter @katanga/sdk-verifier typecheck
pnpm --filter @katanga/sdk-verifier test

CLI

katanga-verifier register-verifier --stake 100      # registry.registerVerifier{value: 100 FLR}
katanga-verifier exit-verifier                       # marks exit; stake unlocks after delay
katanga-verifier withdraw                            # post exit-delay
katanga-verifier claim-rewards                       # pull pending FLR rewards
katanga-verifier check-status                        # registry membership + claimable + balance
katanga-verifier list-disputes --monitor http://localhost:7110
katanga-verifier start                               # long-running runner (delegates to runner.ts)
katanga-verifier aggregator-serve --port 4710        # boot the reference aggregator

All CLI commands read the same env vars as the runner — see .env.example.

Long-running runner

KATANGA_CHAIN_ID=114 \
KATANGA_PRIVATE_KEY=0x... \
KATANGA_VERIFIER_REGISTRY=0x... \
KATANGA_DISPUTE_CONSENSUS=0x... \
KATANGA_AGGREGATOR_PORT=4710 \
KATANGA_MONITOR_PORT=7110 \
pnpm --filter @katanga/sdk-verifier runner

The runner boots in this order:

  1. Resolve chain config from CHAIN_REGISTRY (sdk-core).
  2. Build viem public + wallet clients from KATANGA_PRIVATE_KEY.
  3. Build the evidence fetcher (default: ipfs:// + https:// transports).
  4. Build the adjudicator from KATANGA_ADJUDICATOR (default stub).
  5. Construct VerifierAgent and start watching events.
  6. Optionally start VerifierMonitor (KATANGA_MONITOR_PORT > 0).
  7. Optionally start the reference aggregator (KATANGA_AGGREGATOR_PORT > 0).
  8. Wait for SIGINT/SIGTERM; gracefully stop everything.

EIP-712 vote shape

The signed message is a DisputeVote typed-data struct, frozen by the EP-710 ABI:

struct DisputeVote {
    uint256 escrowId;
    uint8 result;                        // 0 / 1 / 2
    bytes32 evidenceUriHashesAtVoteTime; // keccak256(buyerHash || supplierHash) at startVoting()
    uint256 deadline;                    // == votingDeadline
}

The EIP-712 domain pins chainId and the deployed KatangaDisputeConsensus address:

{
  name: "KatangaDisputeConsensus",
  version: "1",
  chainId,
  verifyingContract,
}

Replay protection comes for free:

  • Different escrow → different escrowId → different digest.
  • Different evidence set → different snapshot hash → different digest.
  • Different chain → different chainId in domain → different digest.
  • Different deployed contract → different verifyingContract → different digest.
  • Past the voting deadline → contract rejects via votingDeadline check.

Evidence URI hashes — exact byte layout

Both sides (verifier signer + S1 contract) MUST agree on the byte layout, otherwise signatures silently fail to recover.

// Per-URI hash (committed on-chain by submitEvidence):
evidenceUriHash(uri) === keccak256(toBytes(uri));
// equivalent in Solidity: keccak256(bytes(evidenceURI))

// Snapshot hash (written into DisputeRecord.evidenceUriHashesAtVoteTime):
evidenceUriHashesSnapshot(buyerHash, supplierHash) ===
  keccak256(concat([toBytes(buyerHash), toBytes(supplierHash)]));
// equivalent in Solidity: keccak256(abi.encodePacked(buyerHash, supplierHash))

Order matters: buyer first, supplier second. Reversing yields a different hash.

If a party never submitted, the bytes32(0) sentinel is used in their slot — the snapshot still hashes deterministically.

Adjudicator interface

interface Adjudicator {
  readonly name: string;
  decide(ctx: AdjudicatorContext): Promise<DisputeResult>;
}

Defaults shipped:

  • StubAdjudicator — always returns BUYER_WINS, logs WARN: stub adjudicator — wire production verdict logic. Replace before pointing at real disputes; running with the stub will slash any verifier that disagrees.
  • ManualAdjudicator — POSTs the context to a configurable webhook (KATANGA_ADJUDICATOR_WEBHOOK) which MUST respond with { "result": 0 | 1 | 2 }.

Custom adjudicators implement Adjudicator and pass through VerifierAgentConfig.adjudicator.

Aggregator

The reference aggregator (Aggregator) stores signatures in-memory keyed by (escrowId, result, signer). It validates each post by recovering the signer locally and (optionally) checking the registry. It is permissionless by protocol design — multiple competing aggregators may coexist.

Endpoints:

  • POST /signatures — accepts SignaturePostBody. Returns { ok: true, recovered }.
  • GET /disputes/:id/signatures — returns the full per-result bucket map.
  • GET /disputes/:id/signatures?result=N — returns just the N bucket as a Hex[].
  • GET /health — unauthed health check.

All routes except /health require Authorization: Bearer <KATANGA_API_AUTH_TOKEN> when a token is configured.

Tests

pnpm --filter @katanga/sdk-verifier test

The shared dispute types live in @katanga/sdk-core/src/dispute.ts and have their own conformance tests in packages/sdk-core/test/dispute.test.ts.

Files

| Path | Purpose | | ----------------------------------------------- | -------------------------------------------------------------- | | src/agent.ts | VerifierAgent — event-driven state machine. | | src/runner.ts | Long-running entry point. | | src/cli.ts | katanga-verifier CLI. | | src/monitor.ts | HTTP /health, /metrics, /disputes/active. | | src/aggregator.ts | Reference signature aggregator HTTP server. | | src/aggregator-client.ts | postSignature, fetchMajoritySignatures. | | src/evidence-fetcher.ts | PluggableEvidenceFetcher + ipfs/https transports. | | src/vote-signer.ts | EIP-712 sign + recover helpers. | | src/dispute-watcher.ts | viem watchContractEvent wrappers. | | src/adjudicator.ts | Adjudicator interface + StubAdjudicator + ManualAdjudicator. | | src/api-auth.ts | Bearer-token helpers. | | src/types.ts | Public + wire-shape types. |