Private Medical Results on Arkiv (Polkadot)
Zero-Knowledge encrypted healthcare data powered by Arkiv's data layer
zk-doctor is a privacy-first medical records system that demonstrates how sensitive healthcare data can be stored securely on Arkiv (Polkadot's queryable data layer) using zero-knowledge encryption.
Medical results contain highly sensitive information. Traditional solutions either:
- 🔴 Store data in centralized databases (single point of failure)
- 🔴 Use blockchain with high costs and no privacy
- 🔴 Lack queryability (IPFS)
zk-doctor combines:
- 🔐 Client-side AES-256-CBC encryption - Data encrypted before leaving browser
- 🔑 Wallet-based access control - Only patient's wallet can decrypt
- 📦 Arkiv storage - Queryable, cost-effective, TTL-based
- ⚡ No gas fees - Polkadot ecosystem benefits
| Feature | Description |
|---|---|
| 🔐 End-to-End Encryption | Medical results encrypted client-side using AES-256-CBC |
| 🔑 Wallet-Based Access | Only the patient's wallet can decrypt their results |
| 📦 Arkiv Storage | Encrypted data stored on Arkiv with queryable annotations |
| ⏰ TTL Support | Automatic expiration after 30 days (configurable) |
| 👨⚕️ Doctor Portal | Simple interface for doctors to create encrypted results |
| 👤 Patient Portal | Secure access for patients to view and decrypt their data |
| 🌐 No Gas Fees | Leverage Polkadot's cost-effective infrastructure |
| 🔍 Queryable | Find results using Arkiv annotations (patient wallet filter) |
┌─────────────────────────────────────────────────────────┐
│ Frontend (React + TypeScript + Vite) │
├────────────────────┬────────────────────────────────────┤
│ 👨⚕️ Doctor Panel │ 👤 Patient Panel │
│ • Mock login │ • Wallet connection │
│ • Medical form │ • Query Arkiv │
│ • Generate token │ • Decrypt results │
└────────────────────┴────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Services Layer (TypeScript) │
├───────────────────────┬─────────────────────────────────┤
│ medicalTokenService │ arkivService │
│ • generateToken() │ • saveMedicalResult() │
│ • decryptToken() │ • getPatientResults() │
│ • AES-256-CBC │ • Arkiv SDK integration │
└───────────────────────┴─────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Arkiv Data Layer (Polkadot Mendoza) │
│ • Queryable entities with annotations │
│ • TTL-based automatic expiration │
│ • No permanent storage costs │
│ • Built on Ethereum/Polkadot infrastructure │
└─────────────────────────────────────────────────────────┘
- Node.js 22+ (or Bun)
- MetaMask (or any Web3 wallet)
- Arkiv Mendoza testnet access
# Clone repository
git clone https://github.com/ETHcali/zk-doctor.git
cd zk-doctor
# Install dependencies
cd demo
npm install
# Start development server
npm run devOpen http://localhost:5173/ 🎉
- Navigate to Doctor tab
- Fill in patient information:
- Patient Name: John Doe
- Patient Wallet:
0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb... - Test Type: Blood Test, X-Ray, MRI, etc.
- Results: Key-value pairs (e.g., "Glucose" = "95 mg/dL")
- Clinical Notes: Optional observations
- Click "Generate Encrypted Result"
- System encrypts data and saves to Arkiv
- Share Entity Key with patient (optional)
- Navigate to Patient tab
- Click "Connect Wallet" (MetaMask)
- System automatically queries Arkiv for your results
- Click "Descifrar" (Decrypt) on any result
- View your medical data securely
- Algorithm: AES-256-CBC
- Key Derivation: Wallet address → SHA-256 hash → 32-byte key
- IV: Random 16-byte initialization vector per token
- Format: JSON serialization
interface EncryptedMedicalToken {
version: string;
encrypted: string; // Hex-encoded ciphertext
iv: string; // Hex-encoded IV
timestamp: number;
}Storage:
await saveMedicalResult(encryptedToken, {
doctorId: 'dr_smith_001',
patientWallet: '0x742d35Cc...',
timestamp: Date.now()
}, 30); // 30 days TTLQuery:
const results = await getPatientResults(patientWallet);
// Returns: MedicalResult[] filtered by annotation.patientAnnotations Used:
type: 'medical_result'doctor: Doctor IDpatient: Patient wallet address (lowercase)timestamp: Creation timestamp
zk-doctor/
├── demo/ # React frontend
│ ├── src/
│ │ ├── components/
│ │ │ ├── DoctorPanel.tsx # Doctor interface
│ │ │ └── PatientPanel.tsx # Patient interface
│ │ ├── services/
│ │ │ ├── arkivService.ts # Arkiv integration
│ │ │ └── medicalTokenService.ts # Encryption
│ │ ├── App.tsx # Main app
│ │ └── main.tsx
│ ├── package.json
│ └── vite.config.ts
├── library/ # Crypto utilities (optional)
├── archive/ # Legacy ZKPJWT files
├── BACKLOG.md # Development tasks
├── ZK_DOCTOR_PLAN.md # Migration plan
└── README.md # This file
| Property | Value |
|---|---|
| Testnet | Mendoza |
| SDK Version | @arkiv-network/sdk v0.4.5+ |
| Faucet | https://faucet.mendoza.arkiv.network/ |
| Explorer | https://explorer.mendoza.arkiv.network/ |
| Docs | https://arkiv.dev.golem.network/docs |
📺 Watch 2-minute demo
(Coming soon after deployment)
- Doctor authentication is mocked (no real auth)
- Private key in code (use environment variables in production)
- Key derivation is simplified (use proper KDF like PBKDF2/Argon2)
- No rate limiting or abuse prevention
- Implement proper doctor authentication (OAuth, SAML, etc.)
- Use hardware security modules (HSM) for key management
- Add RBAC (Role-Based Access Control)
- Implement audit logging
- Add signature verification for data integrity
- Use proper key derivation functions
- Add encryption at rest for Arkiv keys
- Implement rate limiting and DDoS protection
# Build production bundle
npm run build
# Run linter
npm run lint
# Preview production build
npm run previewSee BACKLOG.md → Ticket ZKD-301 for comprehensive E2E testing guide.
Track: Arkiv - Build with Arkiv's Data Layer
Event: Sub0 Polkadot Hackathon 2025
Team: ETHcali
✅ createWalletClient - Write operations (doctor creates entities)
✅ createPublicClient - Read operations (patient queries)
✅ createEntity - Store encrypted medical data
✅ buildQuery - Query by annotations (patient filter)
✅ Annotations - Metadata for queryability
✅ ExpirationTime - TTL support (30 days)
✅ Attributes - Key-value pairs for filtering
This is a hackathon MVP. For production use, please consider:
- Fork the repository
- Implement security enhancements (see above)
- Add comprehensive tests
- Submit PR with improvements
MIT License - See LICENSE file
- Developer: Cristobal Valencia
- GitHub: @ETHcali
- Project: github.com/ETHcali/zk-doctor
- Arkiv Team - For the excellent data layer and comprehensive documentation
- Polkadot - For the Sub0 hackathon opportunity and ecosystem support
- Golem Network - For supporting Arkiv development
- Arkiv Documentation
- Arkiv SDK (TypeScript)
- Sub0 Hackathon
- Polkadot
- BACKLOG.md - Development tasks and tickets
- ZK_DOCTOR_PLAN.md - Migration strategy
- Basic encryption/decryption
- Arkiv integration
- Doctor/Patient portals
- Query by wallet
- Real doctor authentication
- Multi-factor authentication
- Audit logging
- Rate limiting
- PDF export
- Multi-language support (i18n)
- Mobile app
- Integration with EHR systems
Built with ❤️ for the Polkadot ecosystem and the future of private healthcare
"Your health data should be private, secure, and always under your control."