Skip to content

Repository files navigation

MilestoneX API

Decentralized Fundraising & Campaign Management API
Built on NestJS Β· Powered by Stellar Β· Backed by PostgreSQL

NestJS Stellar PostgreSQL


Overview

MilestoneX is a decentralized fundraising platform API that enables transparent, blockchain-verified campaign creation, donation processing, and milestone-based fund releases on the Stellar network. Designed for NGOs, community organizers, and individual fundraisers who demand trustless accountability.

Key Capabilities

  • πŸ” Stellar Wallet Authentication β€” Sign-in with Stellar key-based challenge-response
  • πŸ“‹ Campaign Lifecycle Management β€” Draft β†’ Approval β†’ Active β†’ Completion
  • πŸ’° Blockchain-Verified Donations β€” On-chain transaction tracking and confirmation
  • 🎯 Milestone-Based Fund Releases β€” Smart contract-governed milestone unlocking
  • πŸ”” Real-Time Notifications β€” WebSocket + email notifications for all campaign events
  • πŸ“Š Analytics & Export β€” Campaign stats, donation history, CSV exports
  • πŸ›‘οΈ Admin Dashboard β€” User management, KYC verification, dispute resolution
  • πŸ“ Audit Trail β€” Immutable audit logs for compliance and transparency

Tech Stack

Layer Technology
Runtime Node.js + TypeScript
Framework NestJS (Express adapter)
Database PostgreSQL + Prisma ORM
Cache / Queue Redis + Bull
Blockchain Stellar SDK + Soroban Smart Contracts
Real-Time Socket.IO WebSockets
Monitoring Sentry error tracking
Email Nodemailer (SMTP)
API Docs Swagger / OpenAPI

Project Setup

Prerequisites

  • Node.js >= 18
  • PostgreSQL >= 14
  • Redis >= 6
  • npm or yarn

Installation

# Clone the repository
git clone <repository-url>
cd milestonex-api

# Install dependencies
npm install

# Configure environment
cp .env.example .env
# Edit .env with your database, Redis, and Stellar configuration

Configuration

Update the .env file with your credentials:

# Database
DATABASE_URL="postgresql://user:password@localhost:5432/milestonex?schema=public"

# Redis
REDIS_URL="redis://localhost:6379"

# JWT
JWT_SECRET=your-secure-secret-here

# Email (optional β€” console fallback in development)
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=your-user
SMTP_PASS=your-password
EMAIL_FROM=noreply@milestonex.io

Database Migrations

# Generate Prisma client
npx prisma generate

# Run migrations
npx prisma migrate dev --name init

# (Optional) Open Prisma Studio
npx prisma studio

Running the Application

# Development (hot reload)
npm run start:dev

# Production
npm run build
npm run start:prod

# Debug mode
npm run start:debug

The API will be available at http://localhost:3000 and Swagger docs at http://localhost:3000/api/docs.


Testing

# Unit tests
npm run test

# E2E tests
npm run test:e2e

# Test coverage
npm run test:cov

API Modules

Module Description Endpoints
Auth Stellar wallet challenge-response auth /auth/*
Users Profile, KYC, notification preferences /users/*
Campaigns CRUD, stats, fund release requests /campaigns/*
Donations Donation creation, history, admin tips /donations/*
Milestones Campaign milestone tracking /milestones/*
Contracts Soroban smart contract management /contracts/*
Notifications WebSocket gateway + REST endpoints /notifications/*
Admin User moderation, campaign suspension /admin/*
Health Health checks (DB, Redis) /health
API Keys Programmatic API key management /api-keys/*

API Key Access

API keys are created and revoked via /api-keys/* (JWT-authenticated) and authenticate programmatic requests through the X-API-Key header.

Endpoint Method Scope honored Description
/users/me GET read Returns the key owner's full profile.

GET /users/me accepts either a Bearer JWT or an X-API-Key header. For API-key requests, ScopeGuard validates the scope stored on the key (default read) against the endpoint's honored scopes; a key whose scope is not honored receives 403 Forbidden, and a revoked key (isActive: false) receives 401 Unauthorized. Every other endpoint remains JWT-only.


Project Structure

src/
β”œβ”€β”€ admin/              # Admin dashboard & moderation
β”œβ”€β”€ api-keys/           # API key management
β”œβ”€β”€ audit/              # Audit log entities
β”œβ”€β”€ auth/               # Stellar wallet authentication
β”œβ”€β”€ campaigns/          # Campaign CRUD & lifecycle
β”œβ”€β”€ common/             # Shared guards, decorators, middleware
β”œβ”€β”€ contracts/          # Soroban smart contract services
β”œβ”€β”€ donations/          # Donation processing & admin tips
β”œβ”€β”€ health/             # Health check endpoints
β”œβ”€β”€ milestones/         # Milestone tracking & fund release
β”œβ”€β”€ notifications/      # Email, WebSocket, notification prefs
β”œβ”€β”€ platform/           # Platform tip processing
β”œβ”€β”€ prisma/             # Prisma ORM service & module
β”œβ”€β”€ queue/              # Bull queue configuration
β”œβ”€β”€ redis/              # Redis module
β”œβ”€β”€ stellar/            # Stellar SDK, Soroban, event services
β”œβ”€β”€ throttler/          # Rate limiting
β”œβ”€β”€ users/              # User profiles, KYC, exports
β”œβ”€β”€ app.controller.ts   # Root controller
β”œβ”€β”€ app.module.ts       # Root module
β”œβ”€β”€ app.service.ts      # Root service
└── main.ts             # Application bootstrap & Swagger

CSV Donation Exports

All donation CSV exports (GET /users/me/donations/export and the async queue variant) include the following columns:

Column Notes
Campaign Campaign title at time of export
Amount On-chain amount in the native asset
Asset Asset code (e.g. XLM, USDC)
Date ISO date of the donation (YYYY-MM-DD)
Tx Hash Stellar transaction hash for independent verification

USD Equivalent column is intentionally absent. A hardcoded 0.00 placeholder was previously exported under this heading β€” a medium-severity finding (#15) because downstream consumers (tax tools, accounting software, partner integrations) could silently trust an incorrect value. The column will be reinstated once a verified price-oracle integration (Stellar Horizon order-book snapshots, CoinGecko, or a self-hosted oracle) is in place. Until then, please cross-reference on-chain amounts with your preferred exchange-rate source.


Multi-Asset Campaign Totals

A campaign can accept multiple assets (acceptedAssets: native XLM and/or issued assets such as USDC:<issuer>), so raised totals are never collapsed into a single mixed-unit number.

Field Shape Meaning
raisedByAsset Record<string, string> Per-asset raised totals. Keys are XLM (native) or CODE:ISSUER (issued); values are decimal strings.
raisedAmount decimal string The native-XLM (base asset) portion only. Powers mostFunded browse sorting.
progressPercentage number (0–100) Native-XLM raised Γ· goalAmount (XLM-denominated), capped at 100.

GET /campaigns/:id/stats returns raisedByAsset alongside the native-XLM scalar fields. GET /campaigns/:id/contract-balance reports on-chain balances per asset and never overwrites stored totals.

Fiat conversion is intentionally out of scope. Without a price-oracle integration, heterogeneous assets cannot be converted into a single monetary value. Clients should render raisedByAsset per asset. A future price oracle can feed these per-asset amounts into a USD-equivalent summary without another schema change.


Environment Variables Reference

All configuration is provided via environment variables. Copy .env.example to .env and fill in the values.

Variable Required Default Description
DATABASE_URL βœ… β€” PostgreSQL connection string
REDIS_URL βœ… β€” Redis connection URL
JWT_SECRET βœ… β€” Secret key for signing JWT access tokens
JWT_EXPIRY ❌ 15m JWT token expiry duration
PORT ❌ 3000 HTTP port the server listens on
NODE_ENV ❌ development Runtime environment (development, production, test)
ADMIN_WALLETS ❌ β€” Comma-separated list of Stellar wallet addresses granted the ADMIN role on login
STELLAR_HORIZON_URL ❌ https://horizon-testnet.stellar.org Stellar Horizon API endpoint
SMTP_HOST ❌ β€” SMTP server hostname for email delivery
SMTP_PORT ❌ 587 SMTP port
SMTP_USER ❌ β€” SMTP authentication username
SMTP_PASS ❌ β€” SMTP authentication password
EMAIL_FROM ❌ noreply@milestonex.io Sender address used in outgoing emails
SENTRY_DSN ❌ β€” Sentry DSN for error tracking (disabled if unset)

Security note: Never commit real secrets to source control. Use a secrets manager or CI environment variable injection for production deployments.


Deployment

For production deployment:

# Build the application
npm run build

# Run with Node.js
node dist/main

# Or use a process manager
pm2 start dist/main.js --name milestonex-api

Resources


License

UNLICENSED β€” Proprietary. All rights reserved.

About

Backend services powering MilestoneX, including APIs, indexing, analytics, authentication, notifications, campaign synchronization, transaction monitoring, and integrations with Stellar and Soroban.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages