Portable, zero-knowledge proof of eligibility for cross-border payments.
Do KYC once with a regulated issuer. Then prove you're cleared to any payment corridor — without re-uploading documents and without revealing who you are.
Live demo → · Architecture · Proposal · Roadmap · Handoff · Audit
(If the player above doesn't load, open the video directly.)
Recorded against the live deployment — the contract addresses, policy
data, pass count, and the is_cleared clearance check are all real reads and
a real write against Stellar testnet, not mocked screens.
Every remittance provider, anchor, wallet, and aid program runs its own KYC. The same passport scan and liveness selfie, uploaded again and again — each provider a new custodian of identity data, each a target. The person has no reusable proof that they already passed.
A person completes KYC/AML once with a regulated issuer and receives a signed credential. From then on they prove "I am cleared to use this payment corridor" to any number of providers with a zero-knowledge proof — no documents, no identity, nothing linkable across providers.
┌─ Issuer (off-chain, once) ─────────────┐ ┌─ Holder's device ──────────────┐ ┌─ Stellar / Soroban ───────────────┐
│ runs KYC, then SIGNS a short-lived │ │ Noir → UltraHonk proof of: │ │ corridor_attestation.enter(): │
│ statement with a Grumpkin key: │──▶│ "I hold a valid issuer │──▶│ binds proof ↔ policy, verifies, │
│ { holder_binding, tier, expiry, epoch}│ │ signature meeting this │ │ burns a per-corridor nullifier, │
│ │ │ corridor's policy" │ │ records a PassRecord │
└────────────────────────────────────────┘ └────────────────────────────────┘ └───────────────┬───────────────────┘
│
Midnight (corridor.compact): a public issuer registry — who the operator's payout ── is_cleared()? ──▶ pay
licensed issuers are + each issuer's current credential epoch.
Corridor is Stellar-native. The Midnight contract is a plain public issuer
directory — no shared state, no cross-chain bridge to trust. Revocation is short
expiry plus a monotonic min_cred_epoch floor. See
docs/CREDENTIAL_ACCUMULATOR.md for why the
earlier shared-Merkle-root design was dropped (BLS12-381 vs BN254 — the roots
were values in different fields).
| Sees | |
|---|---|
| A Stellar observer | a pass was granted on corridor C, a tag, an aggregate counter, a burned nullifier — via a fee-sponsoring relayer, so not the holder's account |
| A Midnight observer | the set of licensed issuers and each issuer's current credential epoch — nothing per-credential, nothing per-holder |
| A warranted auditor (target — M7) | only {tier, issuer} for the specific passes in their warrant. Today the auditor blob is a commitment with no opening path — this capability is not yet functional (audit R2-M5). |
| Nobody, on either chain | the holder's identity, documents, tier, expiry, the issuer↔holder link, or their activity across corridors |
| Repo | Contents | CI |
|---|---|---|
| corridor (this) | Hub — docs, the Midnight issuer-registry contract (contracts/), the web app (web/) |
|
| corridor-contracts | Soroban contracts (Rust) — policy registry, attestation, verifier. Owns ABI.md. Live on testnet. |
|
| corridor-circuits | The Noir corridor_eligibility circuit — Grumpkin Schnorr, 73 ACIR opcodes |
|
| corridor-sdk | @corridor/verify — TypeScript SDK for all three roles (issuer, holder, operator) |
|
| Archived — the earlier design's root-sync service, removed under Option B | — |
Full breakdown in COMPONENTS.md.
Pre-MVP research build, participating in the Stellar Drips Wave.
| Layer | State |
|---|---|
Soroban corridor_registry + corridor_attestation + verifier_mock |
✅ 30 host tests; deployed + smoke-verified on Stellar testnet (Option B ABI) |
Noir corridor_eligibility circuit |
✅ 20 tests, real Grumpkin Schnorr verification, nargo execute on a signed fixture (Noir 1.0.0-beta.26) |
@corridor/verify SDK |
✅ 25 tests — Soroban reads, buildWitness, verifyWitnessLocally, 3-step issuance, Grumpkin signer |
| Poseidon2 + Schnorr conformance (circuit ⇄ SDK ⇄ Soroban) | ✅ pinned vectors match; nargo execute on the SDK-signed fixture is the end-to-end check |
Web app (web/) |
✅ public site + live testnet reads + operator clearance checker → corridor-pink.vercel.app |
| Real on-chain UltraHonk verifier | ⏳ M3 — a mock stands in |
Midnight corridor.compact issuer registry |
✅ compiles in CI (6-circuit ZK keyset); deploy tooling Option-B-ready; ⏳ simulator tests + Preprod deploy (M4) |
| Fee-sponsoring tx-relayer + holder/operator flows | ⏳ M6 — docs/TX_RELAYER.md |
Record: corridor-contracts/deployments/testnet.json
| Contract | Address |
|---|---|
corridor_registry |
CDGMQ24E…XJ6 |
corridor_attestation |
CCHWKVRC…L4K |
verifier_mock (M3 placeholder) |
CBN7N7AT…K46Y |
corridor/
├── ARCHITECTURE.md PROPOSAL.md ROADMAP.md HANDOFF.md AUDIT.md COMPONENTS.md DRIPS.md
├── docs/ USAGE · CREDENTIAL_ACCUMULATOR (the Option B decision) · TX_RELAYER · DRIPS_ISSUES
├── contracts/
│ └── corridor.compact Midnight issuer registry (Compact)
├── web/ the public site + operator clearance checker (Vite + React → Vercel)
├── midnight/ Midnight deploy + issuer-ops tooling for corridor.compact
├── assets/ brand — logo.svg, PNGs, favicon
└── vercel.json builds web/ on push to main
# Web app (this repo)
cd web && npm install && npm run dev # → http://localhost:5173
# Midnight issuer registry (needs the Compact compiler, toolchain ≥ 0.34)
compact compile contracts/corridor.compact contracts/managed/corridor
# Stellar contracts
git clone https://github.com/Sconce-Labs/corridor-contracts.git
cd corridor-contracts && cargo test --workspace && cd ..
# Noir circuit (needs noirup)
git clone https://github.com/Sconce-Labs/corridor-circuits.git
cd corridor-circuits/corridor_eligibility && nargo test && nargo executeThis repo — .github/workflows/ci.yml, every push
and PR to main:
| Job | What it does |
|---|---|
web build |
npm ci · npm run typecheck · npm run build in web/ |
Midnight / Compact |
compact compile contracts/corridor.compact |
Doc links |
every relative Markdown link resolves |
main is protected on Midnight / Compact + Doc links. Each sibling repo has
its own CI (see the badges above and each repo's README). A public-input ABI
change is a coordinated PR across corridor-contracts + corridor-circuits +
corridor-sdk.
vercel.json at the repo root builds web/ and every push to main
auto-deploys to corridor-pink.vercel.app.
After a contract redeploy, update web/src/config.ts and
corridor-sdk/src/networks.ts.
Corridor started on Rise In (the "New Moon to
Full" Midnight Builder Challenge) as a single-chain credential circuit, then was
re-scoped as a Stellar-native privacy payments product. It now participates
in the Stellar Drips Wave —
contributors earn from an SDF-funded pool by closing drips-labelled issues
with merged PRs. See DRIPS.md and
docs/DRIPS_ISSUES.md.
Stellar · Soroban (Rust, soroban-sdk 25) · Protocol 25 (BN254, Poseidon2) ·
Noir · UltraHonk · Grumpkin Schnorr · Midnight / Compact · TypeScript · React +
Vite