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.
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.
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" });
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.
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); } }
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.
maxAge to the shortest window your use case tolerates.| Code | Meaning | Action |
|---|---|---|
| INVALID_PROOF | Pairing check failed | Reject. Do not retry. |
| UNKNOWN_NOTARY | Notary key not on allowlist | Reject, or extend the allowlist deliberately. |
| STALE | Timestamp older than maxAge | Ask the holder to re-prove. |
| PREDICATE_MISMATCH | Proof predicate differs from requested | Reject. Check hashing of your predicate string. |
| NULLIFIER_SPENT | Session already used to mint | Read the existing credential instead. |
| HOLDER_MISMATCH | Proof bound to a different address | Reject. Possible replay attempt. |
| Chain | Registry | Verifier | Status |
|---|---|---|---|
| Robinhood Chain | 0x5f1D...a9E2 | 0x9C04...77b1 | testnet |
| Base | 0x5f1D...a9E2 | 0x9C04...77b1 | testnet |
| Ethereum | pending | pending | scheduled |
Full addresses, ABIs, and verification keys are provided with SDK access. Request access.