Verity
Screen-native · StarkNet-readable is_human · Verify-it-yourself receipts

Prove there's a human. Reveal nothing else.

is_human(0x7a3f…91c)true

A passport, a face, and your phone's secure chip become a single yes — proven with zero-knowledge, answered on-chain. Your biometrics never leave the phone. Not even Verity sees them.

The wedge

What makes Verity different

Screen-native

Just a phone and its screen — no hardware orb, no kiosk, no dedicated scanner to ship, run, or trust.

On-chain is_human

A StarkNet contract answers is_human(address). Your proof lives on-chain — it is not trapped in our database.

Verify-it-yourself receipts

Every check leaves a signed Ed25519 receipt you can verify yourself, offline — no call back to Verity.

What a partner gets

A yes/no answer, and the receipt to prove it

A yes/no answer, two ways

Read is_human(address) on StarkNet, or verify a signed Ed25519 receipt offline. These are distinct confirmations — one operator-key-bound on the chain, one user-key-bound in the receipt — and we never flatten them into one word.

Selective disclosure, nothing more

Ask only the attribute you need. Raw date of birth is discarded at enrollment and never stored — age ships as a precomputed yes/no.

is18Plusis21PlusnationalityNo raw date of birth

An illustrative embed — the widget reads a proof and returns a signed receipt for you to verify. It does not itself authenticate a person.

<div id="verity-gate"></div>
<script src="https://verity.id/sdk/idproject.js"></script>
<script>
  IDProject.IDProjectGate.mount(
    document.querySelector('#verity-gate'),
    {
      client: { origin: 'https://verity.id' },
      input: { address: userAddress, action_description: 'Claim one per human' },
      onOutcome: async (o) => {
        if (o.kind !== 'gated') return;
        // reads a proof, returns a receipt — it does not itself authenticate
        const ok = await IDProject.verifyDappReceiptInBrowser(o.receipt);
        if (ok) unlock();
      },
    },
  );
</script>
Honest by construction

What’s real vs demo in this build

This is a proof of concept. Here is exactly what is real, shipping code and what is a demo stand-in in the hosted build — labelled, not buried.

  • real code

    On-phone proof generation

    The biometric-gated key mint and the P-256 zero-knowledge proof are real, shipping code — by design the proof is cryptographically proven and the biometric never leaves the phone.

  • mock

    The hosted demo

    The live deploy runs the chain and prover in mock mode (chain_mode=mock, prover_mode=mock) and relays over the network — it exercises the real end-to-end flow without a live StarkNet write.

  • operator-relayed

    is_human(address) on-chain

    In this build is_human is operator-relayed and operator-asserted: the chain trusts the operator issuer key, not the device key. A live-chain, device-key-bound read is a v1.5 track.

  • demo-only

    Liveness / anti-spoof tier

    The face-liveness verdict is decided on-device and is demo-only — forgeable on a compromised client. The signed tier makes that legible, not prevented (operator-asserted, not proven).

Cryptographically provenBacked by a device-key zero-knowledge proof — checkable without trusting Verity.

Operator-assertedBacked by Verity's operator signature — you trust the operator key, not a proof. We label which is which.

Attribution, not authentication. Some claims are proven by a zero-knowledge proof; others are operator-signed and labelled as such. We never flatten the two.