This is a submission for the MLH x DEV Writing Challenge
What I Built
What if the person betting on an outcome is also the person who can influence it?
That question became our project at VTHacks 14: Not An Insider (Just Lucky).
We built a prediction-market prototype that checks a trader’s identity and recorded affiliations before allowing a trade, rather than treating conflicts of interest as something to investigate afterward.
The name is a joke. The design problem isn’t.
Identity is only the beginning
Knowing who signed a request does not tell you whether they should be allowed to place that trade.
For example, someone affiliated with an athletics department might be restricted from trading on their university’s games, while remaining eligible for unrelated markets. An identity should not need to be globally banned for one conflict of interest.
Our backend connects trader identities to market-specific restrictions. Signed trade requests pass through checks for:
- A valid cryptographic signature.
- A nonce that has not already been used.
- ANS registration validity.
- Affiliation and age restrictions.
- Available account balance.
- Proximity to a declared material event. The timing check is intentionally different: it can flag a trade for review rather than automatically block it. Trade decisions carry reasons and are recorded in a hash-linked audit trail. We wanted an answer to “Why was this blocked?” to be part of the system, not something reconstructed from scattered logs.
The stack
The interface uses HTML, CSS, and JavaScript, with Next.js and TypeScript serving the backend API routes.
Supabase PostgreSQL stores identities, affiliations, markets, replay-protection records, and trade decisions. Polymarket supplies reference market data, alongside simulated markets for demonstrating behavior. Our app does not execute orders on Polymarket.
We deployed the web application on Vercel and used Vitest for automated testing.
The biggest lesson was that a convincing interface and a trustworthy trade pipeline are separate accomplishments. Both matter, but one does not prove the other.
Demo
FluffyCube9343
/
not-an-insider-just-lucky
Prediction markets that check who’s trading and whether they should be.
Not An Insider (Just Lucky)
"Foreknowledge cannot be elicited from spirits, nor from gods, nor by analogy with past events, nor from calculations. It must be obtained from men who know the enemy's situation" -- Sun Tzu, The Art of War
Except half the time that's not insight, it's just who happened to be in the room. And someone on the other end of that trade never knew they didn't have a shot, with no enforcement of trading on public information.
Price discovery, without privileged access.
A pari-mutuel prediction market that enforces conflicts of interest before money moves. Real markets handle insider risk with policy documents and after-the-fact investigations; here the restrictions live in the trade path itself. Every trade is signed in the browser, passes six enforcement gates, and gets a receipt in a hash-chained audit trail — including the blocked ones.
Identities are registered agents in GoDaddy's ANS…
The central demonstration is a comparison between two cases:
- A trader submits a signed request for a market they are eligible to participate in.
- A trader with a restricted affiliation attempts to enter a related market. The backend is designed to explain the different outcomes through its decision records—not simply display a generic error. For example, our demo personas include an athletics-affiliated trader and a technology-company-affiliated trader. Their restrictions apply to relevant markets instead of preventing participation everywhere. Public-demo limitation: banking endpoints are currently disabled on our public deployment while account-ownership authorization is completed. Some private profile fields are also withheld. The hosted site is a prototype, not a production-ready financial service, and end-to-end payment behavior still needs further verification.
Partner Technologies
GoDaddy ANS: connecting identity to signed requests
We used GoDaddy’s Agent Name Service (ANS) in the trader identity-validation flow.
Our demo represents traders using registered agent identities. The browser signs a canonical trade payload, and the backend verifies that signature against the stored public key. It then checks the identity against ANS, including registration status and key consistency.
A trade payload includes fields such as:
tradeId
agentId
marketId
outcome
amount
nonce
timestamp
The field order matters because the signer and verifier must agree on the exact bytes being signed. Two JSON objects can represent the same information while producing different signatures if serialized differently.
The private key is used in the browser for signing; the backend receives the request and its signature.
ANS gave us a way to connect a request to a registered identity. Our application still has to decide what that identity is allowed to do.
That distinction became one of our most important design lessons:
Identity validation establishes who is acting. Eligibility checks establish whether that action is allowed.
There is also an important limitation: our affiliations are currently declared data, not independently verified employer or league attestations. ANS does not automatically prove that someone’s claimed affiliation is true.
Capital One Nessie: making account behavior concrete
We developed a Capital One Nessie integration to explore how trade decisions connect to simulated banking accounts.
The integration includes server-side account operations and code paths for recording simulated movements between trader accounts and a market pool. Nessie uses sandbox data—not real customer funds.
Working with it pushed us beyond a frontend balance counter. We had to consider account identifiers, persistent wallet links, ledger records, and what the interface should show when the provider is unavailable.
It also exposed a difficult systems problem: a payment operation and a database update are not one atomic action.
If one succeeds and the other fails, simply returning “trade failed” may leave the application in an inconsistent state. Retrying blindly can make that worse. Reliable reconciliation is therefore part of our remaining work.
We also found that hiding an API key on the server is necessary but insufficient. The server still needs to verify that a caller owns the account they are trying to access. That is why we disabled the public banking endpoints until those controls are ready.
Supporting infrastructure
Supabase gave us a managed PostgreSQL database so we could spend more of the hackathon on trade screening and the interface.
Vercel provided the public deployment, with backend credentials stored as server-side environment variables. We also used Codex to assist with implementation, debugging, testing, and deployment checks.
These tools helped us move quickly, but integration still required careful review—especially when independently developed pieces started sharing the same identity, account, and trade data.
Hackathon Experience
We built this project at VTHacks 14, working as a team across the interface, identity integration, backend, and account workflows.
The most memorable part of the build was bringing those pieces together. A teammate’s CLI flow could be working while the browser still expected an older data format. A database change could support a new feature while breaking an assumption elsewhere. Even figuring out which frontend version we were running became part of the experience.
That made communication as important as coding. We had to coordinate GitHub changes, agree on request formats, and test the connections between features—not just each feature individually.
We came away with three lessons:
- A signature is not an authorization policy. A correctly signed request can still be ineligible.
- An audit trail needs careful claims. Hash links can help detect changes when verified; they do not make a database magically impossible to alter.
- Deployment is another test environment. A successful build does not prove that authentication, payments, and user flows are ready for unrestricted public use. Our next steps are to finish account authorization, strengthen payment reconciliation, expand end-to-end tests, and move toward independently attested affiliations. We are not claiming to have eliminated insider trading. We built a prototype around a narrower question: Can a market check known conflicts before accepting a trade—and make that decision understandable afterward? That is the idea we want to keep developing.
Teammates: https://github.com/FluffyCube9343, https://github.com/AbhiramRuthala
Top comments (0)