Inspiration

Sharing a patient record today is binary — a regulator, insurer, or researcher either gets the full chart, or gets nothing. GNU Health, real open-source hospital software adopted by the UN as a Digital Public Good and deployed in national health systems across Argentina, India, Jamaica, Laos, Cameroon, and Suriname, has no way to prove one narrow fact about a patient — a vaccination status, a lab result, a critical flag — without exposing the entire record. We built Chart to add exactly that missing piece, using Midnight's zero-knowledge proofs.

What it does

Chart adds a real "Request Disclosure" action to GNU Health's own patient record view. A clinician or institution commits a patient's vaccination, lab result, and critical-flag data as cryptographic bundle commitments — the raw data never leaves the hospital's system. The institution then issues a scoped, expiring, revocable disclosure token to a specific outside identity — a regulator, insurer, or researcher — limited to exactly the bundle category they need. That external party, using a standalone verifier app with zero access to the hospital system, runs a real zero-knowledge proof and receives back one thing: pass or fail. Nothing else about the record is ever disclosed.

How we built it

  • Contracts: 7 Compact circuits (submitRecordBundle, withdrawRecordBundle, issueDisclosureToken, revokeToken, and three typed verify circuits — verifyVaccinationBundle, verifyLabResultBundle, verifyCriticalFlagsBundle), 52 passing tests, real compiled proving/verifying keys for each.
  • Bridge service: a Node/TypeScript service wrapping the Midnight SDK, deployed against a persisted, stable contract address (survives service restarts by rejoining rather than redeploying).
  • Tryton module: a custom GNU Health module (health_midnight_disclosure) adding a real "Request Disclosure" action to the patient form, pulling that patient's actual vaccination/lab/critical-flag data from GNU Health's own database.
  • Standalone verifier app: a separate frontend an external party uses to check a disclosure — generates its own identity locally, never touches the hospital system.
  • All demo data is GNU Health's own official synthetic demo dataset (gnuhealth-50-demo) — no real patient data was used anywhere.

Challenges we ran into

  • A duplicate WASM module bug: midnight-js-protocol pinned an older, separately-loaded copy of onchain-runtime-v3 than our own dependencies, causing an instanceof mismatch (expected instance of StateValue) on every real circuit call. Root-caused by tracing the exact package pin, fixed by forcing a single resolved version tree-wide via an npm override.
  • A silent null rejection: Midnight's levelPrivateStateProvider unconditionally rejects a legitimately-stored null private state — fixed by using {} instead.
  • WSL2 networking: host.docker.internal doesn't route into the WSL2 network namespace where our bridge listens — fixed by using WSL2's own interface address directly.
  • A Tryton UI dead end: clicking a patient's name in the list view follows a many2one relation to an unrelated party.party record, not the actual patient record — traced by reading Tryton's own client source, fixed by targeting the list row itself.
  • Contract address instability: the bridge deployed a fresh contract on every restart. Fixed by persisting the deployed address and having every subsequent startup rejoin the existing contract instead.

Accomplishments we're proud of

A complete, honest, end-to-end chain: real hospital software, real synthetic patient data, real compiled circuits, a real cross-language integration (Python/Tryton to TypeScript/Midnight), and a real independent verifier identity that never touches the hospital system — including real on-chain rejection of tampered data and out-of-scope access attempts.

What we learned

Integrating a mature, real-world open-source application is a genuinely different kind of challenge than building a privacy layer from scratch — most of the hardest problems here were in the seams between systems (Python and TypeScript, WSL and Docker, an unfamiliar ORM and an unfamiliar ZK runtime), not in the zero-knowledge design itself.

What's next

Real credential issuance for institutions (currently a hackathon-scope simplification), a fully in-UI token-issuance flow inside Tryton (currently one step still requires a direct API call), and dynamic Merkle-based supplier/ institution verification in place of the current pre-verified-flag approach.

Built With

Share this project:

Updates

Submission history