Skip to content

Repository files navigation

SilentPay

Privacy-first payroll on the Midnight Network

CI License: MIT Node.js Midnight

SilentPay lets employers run payroll and employees claim payments without publishing individual salary amounts on-chain. Zero-knowledge proofs verify each claim while keeping allocations confidential.

Live demo · Report bug · Request feature


Why SilentPay?

On a transparent blockchain, every payment is permanent and public. Salaries, bonuses, and contractor fees become visible to anyone. SilentPay solves this by running payroll on Midnight, where:

  • Payroll creation and claim counts are publicly verifiable.
  • Individual payment amounts remain hidden.
  • Employees prove eligibility with a ZK circuit — no amount is disclosed on-chain.

Features

  • Privacy-preserving payroll — create payroll with private allocations; only metadata is public
  • ZK claim flowclaimPayment circuit proves eligibility without revealing amounts
  • Wallet integration — Lace wallet connect/disconnect on Midnight networks
  • Full dashboard — manage employees, create payrolls, view claims and history
  • Multiple networks — Preview, Preprod, and local Docker devnet
  • 42 automated tests — contract, validation, service, and end-to-end coverage

Screenshots

The application flow — from landing to payroll execution and employee claiming:

Hero Add Employees
Hero Add Employees
Employees Create Payroll
Employees Create Payroll
Payroll Employee Claim Tab
Payroll Employee Claim Tab
Employee History Employee Dashboard
Employee History Employee Dashboard
Claims Employer Dashboard
Claims Employer Dashboard

Quick start

Prerequisites

Requirement Version
Node.js 22+
PostgreSQL 16+
Docker with Compose v2
Compact compiler ~/.local/bin/compact

Install and run

git clone https://github.com/janvi100104/SilentPay.git
cd SilentPay
npm ci
cp .env.example .env.local
npx prisma generate
npx prisma db push
npm run dev

Open http://localhost:3000.

Quick database with Docker
docker run --name silentpay-db \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=silentpay \
  -p 5432:5432 \
  -d postgres:16

Then set DATABASE_URL=postgresql://postgres:postgres@localhost:5432/silentpay in .env.local.

Compile and deploy the contract

compact compile contracts/payroll.compact contracts/managed/payroll
npm run midnight:deploy
Deploy to local devnet instead
docker compose up -d --wait
npm run midnight:deploy -- undeployed

Run tests

npm test -- --runInBand

Or with coverage:

npm run test:coverage

End-to-end check against the live contract:

npm run test:e2e

Deployed contracts

Network Contract Address Deployer Wallet Address
Preview 972fbdf9ad5adcb3bd363d6528cf68dadf960b2fc962e5f619bb94a452f5fd8a mn_addr_preview1ts073zl6xyp9ragecxh79t97wqpsvu4pzddh9x4l6dg9rggd38cselcd6v
Local devnet 57f93e63fa0a26312da02aa05110b9f2add249322c81933428a15d89677f617b mn_addr_undeployed1h3ssm5ru2t6eqy4g3she78zlxn96e36ms6pq996aduvmateh9p9sk96u7s

Demo video

Watch the demo

Full demo video on Google Drive

Evidence

Compile output Test output Deployed address
Compile output Test output Deployed address

Scripts

Command Description
npm run dev Start the development server
npm run build Production build
npm run compile Compile the Compact contract
npm run midnight:deploy Deploy to the active Midnight network
npm run midnight:network Show or switch the active network
npm run midnight:check-balance Print tNIGHT and DUST balances
npm run midnight:cli Inspect deployment and network state
npm run test Run all tests
npm run test:coverage Tests with coverage report
npm run test:e2e End-to-end contract verification
npm run lint Run ESLint
npm run clean Remove generated artifacts

Architecture

contracts/
  payroll.compact               # Compact payroll contract (createPayroll + claimPayment)
  managed/payroll/              # Compiled artifacts (JS, keys, zkir)
src/
  app/                          # Next.js pages and API routes
    api/claim/                  # Claim API — wires claimPayment circuit
    api/payroll/                # Payroll API — deploys contract
  features/                     # UI components (employee, payroll, claim)
  services/                     # Application services
  midnight/                     # Network config, wallet, deploy scripts
  __tests__/                    # Contract and validation tests
docs/                           # Product, architecture, and schema docs
scripts/e2e-check.ts            # End-to-end verification
docker-compose.yml              # Local Midnight node, indexer, proof server

Privacy model

SilentPay separates public ledger state from private witness data.

Public: payroll ID, employer address, month, employee count, claim count, contract addresses.

Private: allocation amounts, eligibility details, whether a specific address has a positive allocation.

The claimPayment circuit proves an eligible allocation exists, marks it claimed, and increments the public counter — without disclosing the amount.

An observer can learn An observer cannot learn
Payroll metadata Individual salary or payment amount
Claim count and proof activity Another employee's allocation
Publicly disclosed addresses Private witness values

This model does not hide information voluntarily revealed outside the contract. Never commit wallet seeds, private keys, .env files, or deployment state.

Contributing

See CONTRIBUTING.md for guidelines.

Security

To report vulnerabilities, see SECURITY.md.

License

This project is licensed under the MIT License.

About

Privacy-first payroll on Midnight Network — zero-knowledge proofs verify claims without exposing salary amounts on-chain

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages