EarnProof is an open-source, privacy-focused income and payment verification protocol built on Stellar.
This repository contains the NestJS API for wallet authentication, Stellar payment indexing, payment classification, minimum-income proof issuance, public proof verification, proof revocation, optional contract anchoring, and operational health. Issuer management, webhooks, API keys, and audit-log expansion are planned but not yet wired into the application.
The backend is the trust and verification service for EarnProof. It should let workers create signed credentials from qualifying Stellar testnet payments while preventing verifiers from seeing full wallet history, unrelated transactions, total balances, or hidden income details.
The first implementation targets Stellar testnet, Freighter wallet authentication, and signed JSON credentials.
Implemented:
- NestJS application shell
- Versioned
/api/v1prefix - Environment validation
- Swagger documentation at
/docs - Health endpoint at
/api/v1/health - Wallet challenge generation at
/api/v1/auth/challenge - Freighter-compatible SEP-53 challenge verification at
/api/v1/auth/verify - Bearer-token session lookup and logout endpoints
- Incoming Stellar testnet payment synchronization at
/api/v1/payments/sync - Authenticated payment listing, detail lookup, and manual classification
- Minimum-income proof creation at
/api/v1/proofs/minimum-income - Public proof verification at
/api/v1/proofs/:id/verify - Authenticated proof revocation at
/api/v1/proofs/:id/revoke - Deterministic credential canonicalization, hashing, and HMAC signing
- AES-256-GCM protection for indexed payment amounts
- Optional Stellar CLI proof commitment anchoring, revocation, and public status checks for deployed proof registry contracts
- PostgreSQL and Redis Docker Compose services
- Prisma lifecycle service
- Prisma schema for core product entities
- Initial database migration
- Seed script for native XLM testnet asset
- Jest tests for auth, token handling, health, Stellar payment mapping, payment sync/classification, and proof issuance/verification states
Core entities currently modeled:
- Users
- Wallet challenges
- Organizations
- Issuers
- Supported assets
- Payments
- Trusted sources
- Proofs
- Proof claims
- Attestations
- Verification events
- API keys
- Webhooks
- Audit logs
Planned next:
- Issuer management
- Webhooks and API keys
- Database-backed verification event enrichment
- End-to-end API tests with a test database
- NestJS
- TypeScript
- PostgreSQL
- Prisma
- Redis
- Stellar JavaScript SDK
- BullMQ, planned for background jobs
- OpenAPI/Swagger
- Jest
- Docker Compose
src/
app.module.ts
main.ts
auth/
config/
common/
database/
health/
payments/
proofs/
stellar/
prisma/
schema.prisma
seed.ts
migrations/
test/
docs/
npm install
cp .env.example .env
docker compose up -d
npm run prisma:generate
npm run prisma:migrate
npm run start:devDefault local API:
http://localhost:4000/api/v1
Health check:
GET http://localhost:4000/api/v1/health
Swagger docs:
http://localhost:4000/docs
NODE_ENV=development
PORT=4000
DATABASE_URL=postgresql://earnproof:earnproof@localhost:5432/earnproof
REDIS_URL=redis://localhost:6379
APP_URL=http://localhost:3000
API_URL=http://localhost:4000
STELLAR_NETWORK=testnet
STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org
STELLAR_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
SESSION_SECRET=replace_me
CREDENTIAL_SIGNING_SECRET=replace_me
PAYMENT_ENCRYPTION_KEY=MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=
CONTRACT_ANCHORING_ENABLED=false
CONTRACT_ANCHORING_REQUIRED=false
STELLAR_CLI_PATH=stellar
STELLAR_CLI_SOURCE=
PROOF_REGISTRY_CONTRACT_ID=
EARNPROOF_ISSUER_ADDRESS=
EARNPROOF_SCHEMA_VERSION=1Use strong secrets outside local development. Do not commit .env.
Contract anchoring stays disabled unless CONTRACT_ANCHORING_ENABLED=true and the Stellar CLI source, proof registry contract ID, and issuer address are configured. Set CONTRACT_ANCHORING_REQUIRED=true only when proof creation must fail if on-chain registration fails.
npm run prisma:generate
npm run lint
npm run test
npm run build
npm audit --omit=devPrisma validation:
$env:DATABASE_URL='postgresql://earnproof:earnproof@localhost:5432/earnproof'
npx prisma validate- Do not log raw wallet signatures.
- Do not log exact income values.
- Protect stored payment amounts with
PAYMENT_ENCRYPTION_KEY. - Do not expose selected source transactions to verifiers.
- Store API keys as hashes only.
- Store webhook secrets as hashes or encrypted values.
- Hash wallet identifiers in public proof payloads.
- Keep credential signing keys out of source control.
- Treat public verification responses as intentionally disclosed data only.
- Keep backend revocation and public verification aligned with contract status when anchoring is enabled.
- Keep Stellar mainnet disabled until contracts and security posture are reviewed.
earnproof-frontend: Public app, worker dashboard, issuer UI, verifier UI, and admin UI.earnproof-contracts: Soroban issuer registry, proof commitment registry, revocation state, and protocol configuration.earnproof-sdk: Future TypeScript SDK for integrations.earnproof-specification: Future credential and verification standard.