REDACT / Verify
Verifier documentation

Accept a credential from a contract or a backend.

Two integration paths. Onchain: call the registry from your contract. Offchain: verify the proof in your server with the SDK. Both check the same public inputs.

Install

shellnpm
npm install @redact/verify

The package ships the circuit verification key, the notary allowlist for each chain, and a typed client. No network access is required for offchain verification.

SDK

verify.tstypescript
import { verify, Registry } from "@redact/verify";

// offchain: verify a proof object presented by the holder
const result = await verify(proof, {
  origin:    "instagram.com",
  predicate: "follower_count >= 100000",
  maxAge:    "7d",
  notaries:  ["redact-tee-01", "redact-tee-02"],
});

if (!result.valid) throw new Error(result.reason);
admit(result.holder);

// onchain read: check an existing credential by holder
const registry = new Registry({ chain: "robinhood" });
const cred = await registry.get(holder, {
  origin: "instagram.com", predicate: "follower_count >= 100000"
});

Contract

The registry exposes a single view function for gating. It returns true if the holder has a live credential matching the origin and predicate hashes, issued within the requested window.

Gate.solsolidity
interface IRedactRegistry {
  function has(
    address holder,
    bytes32 originHash,
    bytes32 predicateHash,
    uint64  maxAge
  ) external view returns (bool);
}

contract Drop {
  IRedactRegistry constant REDACT = IRedactRegistry(0x5f1D...);
  bytes32 constant ORIGIN = keccak256("instagram.com");
  bytes32 constant PRED   = keccak256("follower_count>=100000");

  function mint() external {
    require(REDACT.has(msg.sender, ORIGIN, PRED, 7 days), "not eligible");
    _mint(msg.sender);
  }
}

Public inputs

commitmentbytes32, hash of ciphertext and session metadata
originHashbytes32, keccak256 of the hostname
pathHashbytes32, keccak256 of the pinned field path
predicateuint8 comparator plus int128 threshold
timestampuint64, notary-attested session time
notaryIdbytes32, key identifier on the allowlist
holderaddress, bound into the proof to prevent theft
nullifierbytes32, derived from commitment, enforces single use

Notary policy

Each deployment maintains an allowlist of notary keys with attestation metadata. Verifiers can accept the default set, restrict to TEE-attested keys only, or require k of n signatures. The SDK exposes the same policy options as the contract.

Recommendation. For anything with financial consequence, require at least two independent notaries and set maxAge to the shortest window your use case tolerates.

Errors

CodeMeaningAction
INVALID_PROOFPairing check failedReject. Do not retry.
UNKNOWN_NOTARYNotary key not on allowlistReject, or extend the allowlist deliberately.
STALETimestamp older than maxAgeAsk the holder to re-prove.
PREDICATE_MISMATCHProof predicate differs from requestedReject. Check hashing of your predicate string.
NULLIFIER_SPENTSession already used to mintRead the existing credential instead.
HOLDER_MISMATCHProof bound to a different addressReject. Possible replay attempt.

Deployments

ChainRegistryVerifierStatus
Robinhood Chain0x5f1D...a9E20x9C04...77b1testnet
Base0x5f1D...a9E20x9C04...77b1testnet
Ethereumpendingpendingscheduled

Full addresses, ABIs, and verification keys are provided with SDK access. Request access.