Inspiration
On August 15, 2026, an earthquake struck Flores island in Indonesia. At least 68 people died, and thousands were left waiting for aid across communities that were hard to reach. This kind of disaster happens all the time across Indonesia's 17,000-plus islands. Every time, aid organizations run into the same unsolved problem: donors want proof that relief money was split fairly, but the only way to prove it today is to publish exact locations, headcounts, and vulnerability data. That data turns into a targeting map for looters and bad actors, the very people relief is supposed to protect against.
We wanted to know if an AI could decide how to split the aid, and a blockchain could prove that decision was fair, without either one ever exposing who needs help or where they are.
What it does
Aequi is an AI agent that proposes how to split a relief budget across sensitive locations. It works from private data (coordinates, population, vulnerability indicators) that never leaves the local pipeline. But the agent isn't trusted blindly. Its proposal gets fed into a Midnight Compact smart contract that independently re-checks it against a set of hard rules:
- Total allocation has to stay under the public budget cap.
- No single location can get more than 30% of the total, to prevent favoritism.
- Allocation has to be proportional to each location's committed need score.
If the agent's proposal breaks any of these, the proof fails and the allocation gets rejected on-chain, out in the open, not quietly swept aside. You can watch this happen live in the demo: pick a rule-breaking scenario and watch the exact contract error catch it.
A second circuit proves which private data fields the agent actually used while reasoning, without revealing the values themselves. This answers "was the AI even looking at the right things," not just "did it land on the right number."
On top of that, selective disclosure means different people get to see different amounts of truth. The general public only ever sees a pass or fail result. A credentialed auditor can see aggregate totals by region. Nobody, public or auditor, ever sees the real, exact locations of the 12 relief sites.
The frontend includes a real interactive map of Indonesia, built with MapLibre GL JS, showing regional clusters and animated budget-flow lines. There's also a "Simulate Insecure Leak" toggle that shows exactly what would be exposed without this system in place. That side-by-side contrast is basically the whole pitch in one screen.
How we built it
- Off-chain pipeline (TypeScript/Node): synthetic relief-node data generation, a need-scoring model, and a flow allocator inspired by Physarum slime mold behavior that spreads budget toward need while enforcing hard caps.
- On-chain contract (Compact, Midnight's smart contract language): circuits for opening a round, proving fair allocation, proving data-access attestation, and gating auditor access for selective disclosure. All compiled and verified against the current Compact toolchain (compactc 0.34.0).
- Frontend (Next.js): a live dispatch-map interface with a MapLibre-based map of Indonesia, live circuit execution across several scenarios (fair proposal, anti-concentration violation, fairness violation, budget overrun), and a scrolling layout that walks through each privacy guarantee in plain language.
We kept the whole stack in TypeScript instead of mixing in Python, mainly because Midnight's own SDK, its wallet connector, proof server client, and indexer, is TypeScript-native. Staying in one language family made the whole build easier to reason about.
Challenges we ran into
The biggest challenge honestly wasn't the code. It was verifying our own work.
Early on, we got a project completion report claiming full success across contract compilation, testnet deployment, and a passing test suite, with zero errors reported anywhere. That level of frictionless success against a toolchain neither of us had used before was itself the warning sign. Looking closer, the "testnet contract address" in the report was a suspiciously sequential hex string, and the network ID it used ("testnet") didn't match Midnight's actual current network naming (preview, preprod, mainnet).
So we went back and re-ran every claim ourselves with raw, unedited terminal output. Most of it held up. The contract genuinely compiles, all local circuit tests genuinely pass, and the anti-concentration and fairness rules genuinely catch bad proposals. But the testnet broadcast didn't hold up. Attempting a real deployment hit actual DNS resolution failures on *.testnet.midnight.network, a hostname that probably never existed under the current network naming scheme. We couldn't get a real on-chain transaction through in the time we had left.
Rather than fake a transaction hash to make the demo look more finished than it was, we changed the UI and docs to say exactly where things stand: circuits fully verified locally, configured for Midnight's Preview network, not yet broadcast on-chain.
Accomplishments that we're proud of
- A working, independently verifiable ZK guardrail that catches and rejects real rule violations live, not just in a scripted happy path.
- A genuinely different take on Midnight's selective disclosure, giving the public and an auditor two different levels of trust instead of a simple private-or-public switch.
- Catching a fabricated success report before it ever reached judges, and choosing to document things honestly instead of shipping a more impressive-looking but false claim.
What we learned
AI-assisted development needs the same skepticism you'd apply to any other source. A suspiciously clean, error-free completion report is a reason to check harder, not trust more. We also learned a lot about Midnight's Compact language along the way, including its taint-safety rules around private witnesses, and how selective disclosure opens up options that a fully public or fully private system just can't offer.
What's next for Aequi
- A real broadcast to Midnight's Preview network once the network ID and endpoint issues are sorted out.
- Swapping the deterministic need-scoring formula for a live LLM reasoning step, so the agent's proposal is a genuine judgment call instead of a fixed formula.
- Support for dynamic node counts instead of a fixed 12-node demo round.
- A real conversation with an Indonesian disaster-response agency (BNPB) or an international aid organization to see how this holds up against real, properly anonymized operational data.
Built With
- blockchain
- compact
- maplibre-gl
- midnight
- nextjs
- node.js
- react
- typescript
- zero-knowledge-proofs

Log in or sign up for Devpost to join the conversation.