Open source

Contributing to Ghostlist.

Help us build privacy-first allowlist minting. Code, docs, tests, and bug reports are all welcome.

Code

  • +New features for the mint flow
  • +Circuit or proof-server glue
  • +Frontend polish and accessibility
  • +Performance and bundle size

Docs

  • +Clarify the privacy model
  • +Walkthroughs and examples
  • +Translating the FAQ
  • +Architecture diagrams

Reports

  • +Reproducible bug reports
  • +Regressions in the proof path
  • +Browser and wallet compatibility
  • +Security disclosures (private)
01

Fork and clone

Fork the repository, then clone your fork locally. The setup guide walks you through installing the workspace and starting the proof server.

terminal
git clone https://github.com/YOUR_USERNAME/GhostList.git
cd GhostList
npm install
cd frontend && npm install && cd ..
02

Create a branch

Cut a focused branch off main. Branch names read better as feature/<scope>, fix/<scope>, or docs/<scope>.

terminal
git checkout -b feature/your-feature-name
03

Build and test

Run the full test suite before opening a PR. Add a test for any new behaviour you ship.

terminal
npm test
04

Open a pull request

Reference the issue you are closing. Include a short summary, a screenshot or screen recording for UI changes, and a checklist of what you verified manually.

  1. 1PR title follows Conventional Commits (feat, fix, docs, chore).
  2. 2Description lists the change, the rationale, and the testing done.
  3. 3CI is green and the new tests pass locally.
  4. 4No unrelated formatting churn or rebased lockfile noise.

Code standards

Style guide

Rule

TypeScript everywhere

No untyped any without a comment justifying it. Prefer unknown plus a runtime check.

Rule

File organization

frontend/src/hooks for logic, routes/ for pages, components/site/ for UI, lib/ for shared utilities.

Rule

Naming

camelCase for functions and variables, PascalCase for components and types. Names should describe behaviour, not implementation.

Rule

Comments

Comments explain why, not what. The code should be self-documenting; comments are for non-obvious tradeoffs.

Rule

Errors

Every async path handles rejection. Surface the underlying error to the user, not a generic fallback.

Rule

Tests

Cover the happy path, the obvious failure paths, and the edge case that motivated the change.

Commit messages

Conventional
+Good
feat(mint): advance to next unspent entry on already-minted
xBad
fix bug
+Good
docs(faq): explain why the chain cannot recover the list
xBad
updated some files

Bug reports

Help us help you

A useful bug report includes a short summary, the exact steps to reproduce, what you expected versus what happened, and your environment. If the failure involves a transaction, paste the transaction hash from the Midnight Explorer so we can correlate it with the on-chain state.

  • 1One-line summary of the bug
  • 2Steps to reproduce, in order
  • 3Expected versus actual behaviour
  • 4Environment: OS, Node version, browser, wallet version
  • 5Screenshots, screen recordings, or browser console logs

We review for

  • okDoes the PR solve the stated problem in the simplest way?
  • okAre tests added for new behaviour?
  • okDoes the diff stay focused on the change?
  • okIs the user-facing impact clearly described?
  • okDoes the proof path remain auditable?

Security first

  • okCryptographic primitives are not rolled by hand.
  • okNo secrets, mnemonics, or production keys in code or logs.
  • okNullifier logic is unit tested for double-mint.
  • okExternal links use rel=noopener noreferrer.
  • okPrivate state providers do not leak to localStorage.
Community

Questions, ideas, and longer-form discussion.

For design discussions, RFCs, or general questions, open a thread on GitHub Discussions. For Midnight-specific questions, the Midnight docs are the source of truth.