Transparent Charity on Blockchain
Version: 1.0 · Network: Ethereum Sepolia Testnet · Live Demo: https://transpachain.site
Traditional charity platforms suffer from opacity: donors rarely know how funds are spent, milestone completion is self-reported, and refund mechanisms are slow or absent. Fraud, mismanagement, and loss of donor trust remain persistent challenges in the nonprofit sector.
TranspaChain is a blockchain-based charity platform that enforces transparency through:
- On-chain escrow — donations lock in a smart contract until milestones are approved
- DAO governance — donors vote with quadratic weight on milestone release proposals
- Verifiable organizations — only admin-verified wallets can create campaigns
- Impact NFTs — donors receive tiered ERC-721 badges as proof of contribution
- Evidence workflow — organizations upload milestone proof to IPFS; admins review before public voting
This report documents the system architecture, technology choices, workflows, security model, testing, deployment, and limitations of the TranspaChain demonstration platform.
Disclaimer: TranspaChain is deployed on Sepolia testnet only for academic and demonstration purposes. Do not send real funds. See /legal.
| Goal | Implementation |
|---|---|
| Transparent fund flow | DonationVault escrow + on-chain events |
| Donor empowerment | Quadratic voting on GovernanceDAO proposals |
| Org accountability | Milestone proofs + admin evidence review |
| Low-friction UX | Indexed MongoDB cache + real-time Socket.io |
| Portfolio-grade demo | Full Docker deployment on AWS EC2 |
| Role | Description | Primary Actions |
|---|---|---|
| Donor | Individual contributing ETH or USDC | Browse campaigns, donate, vote, claim refunds, collect Impact NFTs |
| Organization | Verified nonprofit wallet (ORG_ROLE) |
Submit org profile, create campaigns, upload milestone evidence, extend deadlines |
| Admin / Verifier | Platform operators with on-chain roles | Verify orgs, approve evidence/proposals, queue/execute governance, reconcile indexer |
TranspaChain is a monorepo with three Git submodules:
transpachain/ # Orchestration, docs, Docker, nginx
├── frontend/ → transpachain-frontend
├── backend/ → transpachain-backend
└── contracts/ → transpachain-contracts
graph TD
Browser["Browser<br/>Next.js 16 · wagmi v2 · viem"]
Nginx["Nginx :443<br/>TLS · /api proxy · 10MB uploads"]
Frontend["Frontend :3000<br/>App Router · Tailwind"]
Backend["Backend :3001<br/>Express · Socket.io · Indexer"]
MongoDB["MongoDB<br/>Indexed events + profiles"]
Pinata["Pinata IPFS<br/>Campaign metadata · Evidence"]
Alchemy["Alchemy RPC<br/>WebSocket + HTTP fallback"]
Sepolia["Sepolia Contracts<br/>CharityCore · Vault · DAO · NFT"]
Browser --> Nginx
Nginx --> Frontend
Nginx -->|"/api/*"| Backend
Backend --> MongoDB
Backend --> Pinata
Backend --> Alchemy
Alchemy --> Sepolia
Browser -->|MetaMask / wagmi| Sepolia
Backend -.->|Socket.io| Browser
- Frontend renders campaign data from the REST API and reads live on-chain state via wagmi/viem (balances, roles, proposal states).
- Nginx terminates TLS, proxies
/to Next.js and/api/to Express, and allows uploads up to 10 MB. - Backend indexer subscribes to Alchemy for contract events, writes MongoDB documents, and emits Socket.io events.
- Pinata pins campaign metadata JSON and evidence images; the backend proxies uploads to avoid exposing API keys in the browser.
- Smart contracts hold escrowed funds and enforce governance rules; no admin can unilaterally drain donor deposits.
Detailed architecture: architecture.md
| Technology | Version | Role in TranspaChain |
|---|---|---|
| Next.js | 16.x | App Router pages for campaigns, governance, dashboard, admin; SSR/SSG hybrid for fast navigation |
| React | 18.x | Component model for modals, panels, wallet-gated org actions |
| TypeScript | 5.x | Type-safe hooks, API client, contract ABIs |
| Tailwind CSS | 3.4 | Dark holo-mint glass UI (globals.css) |
| wagmi | 2.9 | Wallet connect, useReadContract, useWriteContract for all on-chain txs |
| viem | 2.13 | Low-level encoding, Sepolia chain config, Alchemy transport |
| @tanstack/react-query | 5.x | Cached contract reads via wagmi |
| Socket.io client | 4.8 | Live homepage stats and donation feed |
| framer-motion | 12.x | Page transitions and org action panel animations |
| @phosphor-icons/react | 2.x | Consistent iconography across panels |
Connection pattern: lib/wagmi.ts configures Sepolia; lib/contracts.ts loads ABIs and NEXT_PUBLIC_* addresses baked at Docker build; lib/api.ts calls /api/* through nginx.
| Technology | Version | Role in TranspaChain |
|---|---|---|
| Node.js + Express | 4.19 | REST API: campaigns, donations, proposals, orgs, evidence, admin, IPFS |
| TypeScript | 5.x | Typed routes, models, indexer handlers |
| MongoDB + Mongoose | 8.4 | Indexed chain events + off-chain profiles and evidence |
| ethers.js | 6.16 | Event listener, indexedScope on-chain reads, health checks |
| Socket.io | 4.7 | Real-time donationReceived, campaignUpdated, proposalUpdated |
| Alchemy | — | Sepolia RPC/WebSocket for indexer and RPC health rotation |
| Pinata SDK | 2.1 | pinJSONToIPFS (campaign metadata), pinFileToIPFS (evidence images) |
| multer | 2.1 | In-memory file buffer for IPFS upload route (max 10 MB) |
| express-rate-limit | 8.5 | 120 req/min per IP |
Indexer modules: eventListener.ts (live subscription), historicalSync.ts (backfill from DEPLOY_FROM_BLOCK), indexedScope.ts (deployment-scoped queries).
| Technology | Version | Role in TranspaChain |
|---|---|---|
| Solidity | 0.8.20 | Four core contracts on Sepolia |
| Foundry | — | 307 tests — unit, fuzz, integration |
| Hardhat | 2.22 | Deployment scripts to Sepolia |
| OpenZeppelin | 5.6 | AccessControl, ReentrancyGuard, ERC721 |
Campaign registry, org verification gate (ORG_ROLE), creation deposit, deadline extension, finalize/cancel lifecycle.
ETH/USDC escrow per campaign, 1% platform fee, milestone proof submission, refund claims, release only via GovernanceDAO.
Quadratic voting (√donation), 51% quorum, 24h timelock, proposal queue/execute by admin.
ERC-721 donor badges — Bronze/Silver/Gold tiers upgraded on repeat donations.
Contract deep-dive: smart-contracts-explained.md
| Collection | Source | Purpose |
|---|---|---|
campaigns |
CampaignCreated + IPFS |
List/detail, stats, filters |
donations |
DonationReceived |
Donor history, campaign donors |
proposals |
Governance events | Voting UI, approval status |
verifiedorgs |
OrgVerified / OrgRevoked |
Admin verified org list |
orgprofiles |
POST /orgs |
Off-chain org applications |
evidence |
POST /evidence |
Milestone image + description (admin review) |
Schema: er-diagram.md · Data flow: mongodb-guide.md
| Technology | Role in TranspaChain |
|---|---|
| Docker + Compose | frontend, backend, mongodb, nginx services on EC2 |
| Docker Hub | cuongnguyen146/transpachain-frontend, transpachain-backend images |
| Nginx | TLS (Let's Encrypt), /api rewrite proxy, client_max_body_size 10m |
| AWS EC2 | Production host for https://transpachain.site |
| Sepolia | Testnet (chainId 11155111) — all contract interactions |
Deploy guide: deploy.md
Donations lock in DonationVault. Funds release in equal slices per milestone only after governance approval.
Org submits on-chain proof CID → GovernanceDAO proposal → admin off-chain approval → donor quadratic vote → queue → 24h timelock → execute → releaseMilestoneFunds.
First donation mints ERC-721; repeat donations upgrade tier based on cumulative amount (ETH or USDC thresholds).
Off-chain profile review + on-chain verifyOrg() grants ORG_ROLE.
Orgs upload images via POST /api/ipfs/upload (Pinata); metadata stored in evidence collection with approvalStatus: pending until admin approves.
Failed or cancelled campaigns enable proportional claimRefund for donors.
- Connect MetaMask (Sepolia) → browse
/campaigns - Donate ETH/USDC on campaign detail → receive Impact NFT
- Review approved evidence → vote on
/governance/[proposalId] - Claim refund if campaign fails
- Submit profile on
/dashboard→ await admin approval - Receive
ORG_ROLEon-chain → create campaign at/campaigns/create - Upload milestone evidence + on-chain proof CID in Organization actions panel
- Extend deadline (max 2 platform extensions) or finalize/cancel
- Review org profiles and evidence at
/admin - Approve proposals for public voting
- Queue and execute passed proposals after timelock
- Run
POST /admin/reconcile-campaignsafter redeploys
Full workflows: workflow.md · charity-business-flow.md
| Control | Mechanism |
|---|---|
| Escrow integrity | Funds exit only via DAO release or donor refund |
| Org gate | ORG_ROLE required for createCampaign |
| Governance | Quadratic voting + 51% quorum (cast/total power) + majority For + 24h timelock |
| Campaign lifecycle | Funded (goal reached) ≠ Completed; finalize only when expired+underfunded OR all milestones done |
| Refunds | Proportional via _remainingRefundWeight; only Failed/Cancelled |
| Reentrancy | ReentrancyGuard on DonationVault |
| Spam prevention | Campaign creation deposit |
| Admin limits | Cannot drain escrow; can pause, close proposals, configure fees |
| Control | Mechanism |
|---|---|
| Evidence review | Admin approves before donors vote |
| API abuse | Rate limiting, CORS to CORS_ORIGIN |
| Data integrity | indexedScope + reconcile jobs |
| IPFS keys | Pinata credentials server-side only |
Audit notes: security-audit.md
make contracts-test # from monorepo root| Suite | Tests |
|---|---|
| CharityCoreTest | 19 |
| DonationVaultTest | 82 |
| ImpactNFTTest | 43 |
| GovernanceDAOTest | 73 |
| TranspaChainTest (integration) | 50 |
| DonationVaultFuzz (×2) | 40 |
| Total | 307 passed |
Coverage includes donation lifecycle, refunds, governance quorum/timelock, NFT tiers, fuzz invariants, and cross-contract integration.
- Backend indexer sync verified via
GET /health(onChainCampaigns === indexedCampaigns) - Frontend
npm run buildvalidates TypeScript and Next.js compilation - Manual demo checklist: demo-guide.md
- Clone monorepo with submodules
- Configure root
.envfrom.env.example - Build frontend on WSL:
make docker-build-frontend - Push images to Docker Hub
- EC2:
docker compose pull && docker compose up -d
| Contract | Address |
|---|---|
| CharityCore | 0xCE017838BfE2785CB2458bb205770663bEB9b0B8 |
| DonationVault | 0xEb421D07E885EeB2B8E9ea408FF284013F872Db1 |
| GovernanceDAO | 0xd655d85ddACc386901487CE8E1ec45BD4F872A19 |
| ImpactNFT | 0xF2556FcccaE36A6d8Da0C75a863CA7368FC6761a |
| USDC (Sepolia) | 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 |
Details: deploy.md
| Limitation | Notes |
|---|---|
| Sepolia only | No mainnet deployment; test ETH/USDC only |
| Demo scope | Not audited for production use |
| Indexer lag | MongoDB may trail chain during RPC outages |
| Org extension count | Frontend tracks 2 extensions in localStorage (UX policy) |
| IPFS dependency | Upload requires Pinata API keys on backend |
Future work: Mainnet pilot, multisig admin, ZK identity for orgs, mobile wallet support, subgraph alternative to custom indexer, additional stablecoins.
TranspaChain demonstrates how blockchain escrow, DAO governance, and transparent evidence workflows can address trust deficits in charitable giving. The platform combines Solidity smart contracts (307 Foundry tests), a real-time Node.js indexer, and a modern Next.js frontend into a deployable Docker stack on Sepolia testnet.
While scoped as a demonstration project, TranspaChain provides a complete reference architecture for milestone-based charity funding with donor oversight — a model applicable to real-world nonprofit transparency initiatives once extended beyond testnet.
| Document | Topic |
|---|---|
| architecture.md | System overview and data flows |
| system-design.md | Contracts, indexer, security |
| user-manual.md | End-user guide |
| deploy.md | Production deployment |
| security-audit.md | Security analysis |