Transparent Real-Time E-Voting Platform for Nigeria
π Live Demo: https://dpp7dtwwhn3ff.cloudfront.net
During Nigeria's last election, I personally witnessed a candidate win at our polling unit β confirmed by all voters present. However, by the time results were televised, a different candidate was declared the winner of that same polling unit. The manual vote collation process created opportunities for manipulation between the polling station and final announcement.
VoteWatch NG is my response to that experience.
A serverless, real-time e-voting platform where:
- Every vote is immediately visible to all watchers nationwide
- Results are cryptographically immutable using AWS QLDB
- Voters cast ballots from home using their VIN and voter card
- Vote counts aggregate live across Nigeria's 5-tier electoral hierarchy
- Any discrepancy between local count and announced results is instantly detectable
Frontend:
- React 18 (Vite)
- AWS Amplify
- Hosted on S3 + CloudFront (HTTPS)
Backend:
- AWS AppSync β GraphQL API with real-time subscriptions
- AWS Lambda β 3 serverless functions (Node.js 20)
- Amazon DynamoDB β 10 tables for hierarchical data
- Amazon QLDB β Immutable ledger for audit trail
- Amazon Cognito β User authentication
Infrastructure:
- AWS CDK for Infrastructure as Code
- All services within AWS Free Tier
- β Register with email + password
- β Verify identity with VIN and voter card number
- β Cast one secure vote per election
- β Receive cryptographic receipt with Vote ID and QLDB confirmation
- β View live results without authentication
- β Drill down from National β State β LGA β Ward β Polling Unit
- β Real-time updates via WebSocket subscriptions
- β See leading candidate and vote percentages
- β Create elections with time windows
- β Add candidates with party affiliations
- β Open and close voting portals instantly
- β View immutable QLDB audit logs
| Feature | Implementation |
|---|---|
| Double-vote prevention | DynamoDB atomic transactions β vote written AND voter marked as voted simultaneously (both or neither) |
| VIN privacy | SHA-256 hashing β raw VIN never stored, only hash checked against mock INEC registry |
| Vote anonymity | Votes table does NOT contain voter identity β only QLDB audit trail links voter to vote (accessible only to authorized officials) |
| Immutability | QLDB cryptographic hash chain β any tampering mathematically detectable |
| Authentication | Cognito JWT tokens with 8+ char passwords (uppercase, lowercase, digit required) |
votewatch-ng/
βββ backend/
β βββ infrastructure/
β β βββ votewatch-stack.js # AWS CDK infrastructure
β β βββ package.json
β β βββ cdk.json
β βββ lambdas/
β β βββ castVote.js # Vote casting with atomic transaction
β β βββ verifyVoter.js # VIN verification
β β βββ getResults.js # Results aggregation
β β βββ package.json
β βββ seed/
β β βββ seedMockData.js # Populate DB with test data
β β βββ package.json
β βββ schema.graphql # AppSync GraphQL schema
βββ frontend/
β βββ src/
β β βββ App.jsx # Complete React application
β β βββ main.jsx # Entry point with Amplify config
β β βββ aws-config.js # AWS credentials
β β βββ ErrorBoundary.jsx # Error handling
β βββ index.html
β βββ vite.config.js
β βββ package.json
βββ README.md
- Node.js 20+
- AWS Account
- AWS CLI configured with credentials
- AWS CDK installed globally (
npm install -g aws-cdk)
git clone https://github.com/Deranology/votewatch-ng.git
cd votewatch-ng# Install dependencies
cd backend/lambdas
npm install
cd ../infrastructure
npm install
# Bootstrap CDK (first time only)
cdk bootstrap
# Deploy to AWS
cdk deploySave the 4 output values:
UserPoolIdUserPoolClientIdGraphQLApiUrlGraphQLApiKey
cd ../seed
npm install
node seedMockData.jsThis creates:
- 5 States (Lagos, FCT Abuja, Kano, Rivers, Enugu)
- 42 LGAs
- 210 Wards
- 1,050 Polling Units
- 500 Mock Voters
- 1 Active Election
- 4 Presidential Candidates
Update frontend/src/aws-config.js with your CDK output values:
export const awsConfig = {
Auth: {
Cognito: {
userPoolId: "YOUR_USER_POOL_ID",
userPoolClientId: "YOUR_CLIENT_ID",
region: "us-east-1",
},
},
API: {
GraphQL: {
endpoint: "YOUR_GRAPHQL_API_URL",
region: "us-east-1",
defaultAuthMode: "userPool",
},
},
};
export const PUBLIC_API_KEY = "YOUR_API_KEY";cd ../../frontend
npm install
npm run build
# Create S3 bucket
aws s3 mb s3://votewatch-ng-YOUR-NAME --region us-east-1
# Enable website hosting
aws s3 website s3://votewatch-ng-YOUR-NAME \
--index-document index.html \
--error-document index.html
# Disable block public access
aws s3api put-public-access-block \
--bucket votewatch-ng-YOUR-NAME \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
# Set bucket policy
aws s3api put-bucket-policy \
--bucket votewatch-ng-YOUR-NAME \
--policy file://policy.json
# Upload files
aws s3 sync dist/ s3://votewatch-ng-YOUR-NAME --delete# Create CloudFront distribution
aws cloudfront create-distribution \
--distribution-config file://cloudfront-config.json \
--query "Distribution.DomainName" \
--output textThis gives you an HTTPS URL that works in all browsers including Chrome.
Use any of these VIN and voter card combinations:
| VIN | Voter Card |
|---|---|
| AB00000000001 | VC0000000001 |
| AC00000000002 | VC0000000002 |
| AD00000000003 | VC0000000003 |
| AE00000000004 | VC0000000004 |
| AF00000000005 | VC0000000005 |
- Open https://dpp7dtwwhn3ff.cloudfront.net
- Click "Cast Your Vote"
- Register with any email + password (8+ chars, uppercase, lowercase, digit)
- Enter VIN and voter card from table above
- Select a candidate and vote
- View your QLDB receipt
- Click "Watch Live Results" to see real-time aggregation
National (1)
βββ States (5 in demo, 37 in production)
βββ LGAs (42 in demo, 774 in production)
βββ Wards (210 in demo)
βββ Polling Units (1,050 in demo, 176,000+ in production)
| Table | Purpose |
|---|---|
| votewatch-states | 5 Nigerian states |
| votewatch-lgas | LGAs linked to states (GSI: stateId-index) |
| votewatch-wards | Wards linked to LGAs (GSI: lgaId-index) |
| votewatch-polling-units | Polling units linked to wards (GSI: wardId-index) |
| votewatch-voters | Voter records with verification status and hasVoted flag (GSI: vinHash-index) |
| votewatch-inec-mock | Mock INEC voter registry (VIN and card hashes only) |
| votewatch-elections | Election portals with UPCOMING/OPEN/CLOSED status |
| votewatch-candidates | Candidates per election (GSI: electionId-index) |
| votewatch-votes | Individual vote records (NO voter identity for privacy) |
| votewatch-aggregates | Pre-computed running totals at all 5 hierarchy levels |
Table: AuditVotes
- Only place linking voter ID to vote
- Cryptographic hash chain prevents tampering
- Accessible only to authorized officials
- Cannot be deleted or modified (even by AWS root)
Demo deployment (within AWS Free Tier):
| Service | Free Tier | Demo Usage | Cost |
|---|---|---|---|
| DynamoDB | 25 GB storage, 25 WCU/RCU | 10 tables, <1 GB | $0 |
| Lambda | 1M requests/month | ~1,000 requests | $0 |
| AppSync | 250K requests/month | ~500 requests | $0 |
| Cognito | 50K MAU | 10 test users | $0 |
| S3 | 5 GB storage (12 months) | <1 MB | $0 |
| CloudFront | 1 TB transfer (12 months) | <10 MB | $0 |
| Total | $0/month |
Production scale (1M voters, high turnout):
- DynamoDB: ~$50/month
- Lambda: ~$30/month
- AppSync: ~$40/month
- S3/CloudFront: ~$20/month
- Total: ~$140/month for nationwide deployment
This project was my first major AWS deployment after earning my AWS Solutions Architect Associate certification. Key learnings:
Technical:
- AppSync subscriptions for real-time data push (vs polling)
- DynamoDB atomic transactions for data integrity
- QLDB's immutable ledger for audit trails
- CDK Infrastructure as Code patterns
- Lambda cold start optimization
- Cognito user pool configuration
- CloudFront CDN setup for HTTPS delivery
Architectural:
- When to use DynamoDB vs QLDB
- Pre-computing aggregates vs on-demand queries
- Separating voter identity from vote records for privacy
- Hierarchical data modeling for electoral geography
- Serverless cost optimization strategies
- Multi-AZ deployment for high availability
Product:
- Building for a real problem I personally experienced
- Balancing transparency with voter privacy
- Designing for scale (176K polling units nationwide)
- Creating intuitive UX for non-technical voters
- Complete backend architecture
- Frontend with all user flows
- Live deployment with HTTPS
- Mock INEC verification
- Error boundary for graceful failures
- Real INEC API integration
- Biometric verification (fingerprint)
- React Native mobile app
- All 36 states + FCT (774 LGAs, 176K polling units)
- Independent security audit
- Offline vote buffering for low-connectivity areas
- Unit and integration tests
- Pilot with one state electoral commission
- INEC stakeholder presentations
- International observer access portal
- Multi-election support (Presidential, Gubernatorial, Senatorial)
This is currently a portfolio/demonstration project. If you'd like to contribute or discuss production deployment:
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
MIT License β see LICENSE for details.
Chidera Alamezie | AWS Solutions Architect Associate
I built VoteWatch NG after personally witnessing election fraud in Nigeria's last election. This project demonstrates:
- Full-stack AWS serverless architecture
- Real-time data synchronization at scale
- Cryptographic immutability for high-stakes data
- Product thinking beyond engineering
- End-to-end deployment on AWS Free Tier
π Live Demo: https://dpp7dtwwhn3ff.cloudfront.net
π» GitHub: https://github.com/Deranology/votewatch-ng
π§ Email: chideraalamezieprince@gmail.com
πΌ LinkedIn: www.linkedin.com/in/alamezie-chidera-36a2a71b4
- INEC β Nigeria's Independent National Electoral Commission (for electoral hierarchy structure)
- AWS β For Free Tier making this demo possible
- Nigerian voters β Who deserve transparent, fraud-proof elections
VoteWatch NG β Transparency. Integrity. Real-Time Democracy. π³π¬



