A verification node system with both REST and GraphQL APIs for managing user proofs and verifications.
- GraphQL API: Flexible data queries with real-time subscriptions
- REST API: Traditional REST endpoints (for backward compatibility)
- Authentication: JWT-based authentication system
- Real-time Updates: WebSocket subscriptions for live data
- Rate Limiting: Protection against API abuse
- TypeScript: Full type safety throughout the application
- Comprehensive Testing: Unit tests for all GraphQL features
- Node.js (v16 or higher)
- npm or yarn
# Clone the repository
git clone <repository-url>
cd Verinode
# Install dependencies
npm install
# Build the project
npm run build
# Start the development server
npm run devThe server will start on http://localhost:4000
You can also run the application using Docker:
# Build and start the containers
docker-compose up -d
# View logs
docker-compose logs -f- Endpoint:
http://localhost:4000/graphql - Playground:
http://localhost:4000/graphql(development only) - Subscriptions:
ws://localhost:4000/graphql
Base URL: http://localhost:4000/api
Register
- Endpoint:
POST /api/auth/register - Body:
{ "email": "user@example.com", "username": "user", "password": "password" } - Response:
{ "token": "eyJhbG...", "user": { "id": "1", "email": "user@example.com" } }
Login
- Endpoint:
POST /api/auth/login - Body:
{ "email": "user@example.com", "password": "password" }
Get All Proofs
- Endpoint:
GET /api/proofs - Query Params:
page(int),limit(int) - Response:
{ "data": [{ "id": "1", "title": "My Proof", "status": "VERIFIED" }], "total": 1 }
Create Proof
- Endpoint:
POST /api/proofs - Headers:
Authorization: Bearer <token> - Body:
{ "title": "Document Verification", "description": "Verify identity document", "metadata": { "type": "passport" } }
Get Proof by ID
- Endpoint:
GET /api/proofs/:id
Update Proof
- Endpoint:
PUT /api/proofs/:id
Delete Proof
- Endpoint:
DELETE /api/proofs/:id
Common issues and solutions:
-
401 Unauthorized
- Cause: Missing or invalid JWT token.
- Solution: Ensure the
Authorizationheader is set toBearer <your-token>.
-
429 Too Many Requests
- Cause: Rate limit exceeded.
- Solution: Wait for the window to reset (check
X-RateLimit-Resetheader).
-
Connection Refused
- Cause: Server is not running.
- Solution: Run
npm run devornpm start.
The GraphQL API provides the following main types:
- User: User accounts and authentication
- Proof: Verification proofs with status tracking
- AuthPayload: Authentication responses
- Subscriptions: Real-time updates for proof changes
# Get current user
query {
me {
id
email
username
}
}
# Get paginated proofs
query {
proofs(first: 10, status: PENDING) {
edges {
node {
id
title
description
status
}
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}# Login
mutation {
login(email: "user@example.com", password: "password") {
token
user {
id
email
}
}
}
# Create proof
mutation {
createProof(
title: "My Proof"
description: "Proof description"
metadata: { type: "document" }
) {
id
title
status
}
}# Subscribe to proof updates
subscription {
proofUpdated(userId: "1") {
id
title
status
updatedAt
}
}The API uses JWT tokens for authentication. Include the token in the Authorization header:
Authorization: Bearer <your-jwt-token>For WebSocket subscriptions, include the token in the connection parameters:
const wsClient = new SubscriptionClient('ws://localhost:4000/graphql', {
connectionParams: {
Authorization: `Bearer ${token}`
}
});Different rate limits apply to different operation types:
- Queries: 60 requests per minute
- Mutations: 30 requests per minute
- Authentication: 5 attempts per 15 minutes
Rate limit headers are included in responses:
X-RateLimit-Limit: Maximum requests for the windowX-RateLimit-Remaining: Remaining requests in the windowX-RateLimit-Reset: Unix timestamp when the window resets
# Development server with hot reload
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run tests
npm test
# Run tests in watch mode
npm run test:watchsrc/
├── graphql/
│ ├── schema.ts # GraphQL type definitions
│ ├── server.ts # Apollo Server setup
│ ├── resolvers/ # Query and mutation resolvers
│ │ ├── userResolver.ts
│ │ └── proofResolver.ts
│ ├── subscriptions/ # Subscription handlers
│ │ └── proofSubscription.ts
│ ├── middleware/ # Custom middleware
│ │ ├── auth.ts
│ │ └── rateLimit.ts
│ └── __tests__/ # GraphQL tests
│ ├── resolvers.test.ts
│ └── subscriptions.test.ts
├── types/
│ └── index.ts # TypeScript type definitions
├── test/
│ └── setup.ts # Jest test setup
└── index.ts # Application entry point
The project includes comprehensive tests for all GraphQL features:
# Run all tests
npm test
# Run tests with coverage
npm test -- --coverage
# Run specific test file
npm test -- resolvers.test.ts- Migration Guide:
docs/graphql/migration-guide.md - Schema Documentation:
docs/graphql/schema-documentation.md
# Server configuration
PORT=4000
NODE_ENV=development
# JWT configuration (for production)
JWT_SECRET=your-secret-key
JWT_EXPIRES_IN=7d
# Database configuration (for production)
DATABASE_URL=your-database-urlMVP website analytics is integrated in the React SPA under frontend/src/analytics.
Create frontend/.env (or frontend/.env.local) and set your GA4 measurement ID:
REACT_APP_GA_ID=G-XXXXXXXXXXAnalytics is disabled by default in local development unless this ID is explicitly configured.
frontend/src/analytics/ga.ts- Loads Google
gtag.jsonce - Initializes GA4
- Exposes
trackEvent({ action, category, label, value }) - Exposes auth helpers
trackLogin()andtrackSignup()
- Loads Google
frontend/src/analytics/RouteChangeTracker.tsx- Sends SPA
page_viewevents on route changes
- Sends SPA
frontend/src/pages/Home.tsx- Tracks homepage CTA clicks (
Issue Proof,Verify Proof)
- Tracks homepage CTA clicks (
frontend/src/components/Navbar.tsx- Tracks top navigation clicks
frontend/src/pages/IssueProof.tsx- Tracks proof issue form submits/success/errors
frontend/src/pages/VerifyProof.tsx- Tracks proof search submits/success/errors and on-chain verify CTA
frontend/src/pages/Marketplace.jsx- Tracks create template CTA and key submit actions (create/purchase/rating)
frontend/src/analytics/webVitals.ts- Captures LCP, CLS, INP, FID, and TTFB and forwards as GA events
- Start the frontend with
REACT_APP_GA_IDset. - Open the app and navigate across pages.
- Trigger key actions (CTA clicks, form submits, verify on-chain, etc.).
- In GA4, open
Admin -> DebugView. - Confirm events such as
page_view,cta_click,form_submit, andweb_vital_*.
The current frontend routes do not expose login/signup UI yet. When those screens are added, call trackLogin() and trackSignup() (or trackEvent(...) directly) in their submit handlers.
- Set environment variables
- Build the project:
npm run build - Start the server:
npm start
For production, ensure:
NODE_ENV=production- Use a proper database instead of mock data
- Use a secure JWT secret
- Configure proper CORS origins
- Set up SSL/TLS
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new features
- Ensure all tests pass
- Submit a pull request
This project is licensed under the MIT License.