A decentralized encrypted file vault built on Sui + Walrus + zkLogin.
- Zero-Knowledge Authentication: Login with Google using zkLogin (no passwords!)
- End-to-End Encryption: Files are encrypted client-side before upload
- Decentralized Storage: Files stored on Walrus (decentralized blob storage)
- On-Chain Metadata: File metadata secured on Sui blockchain
- Secure Sharing: Share encrypted files with other users via Sui addresses
┌─────────────┐
│ Frontend │ (React + TypeScript + Tailwind)
│ (zkLogin) │
└──────┬──────┘
│
├─────────────┐
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ Walrus │ │ Sui Chain │
│ (Storage) │ │ (Metadata) │
└─────────────┘ └──────────────┘
- Node.js 18+
- Sui CLI (Installation guide)
- Google OAuth Client ID (Setup guide)
cd walrus-vault/frontend
npm installCreate .env file:
VITE_ZKLOGIN_CLIENT_ID=your-google-client-id
VITE_ZKLOGIN_REDIRECT_URI=http://localhost:5173/auth/callback
VITE_SUI_NETWORK=testnet
VITE_SUI_PACKAGE_ID=<deployed-package-id>
VITE_WALRUS_API_URL=https://publisher.walrus-testnet.walrus.space
VITE_WALRUS_AGGREGATOR_URL=https://aggregator.walrus-testnet.walrus.spacecd ../move
sui client switch --env testnet
sui move build
sui client publish --gas-budget 100000000Copy the published package ID to .env as VITE_SUI_PACKAGE_ID.
cd ../frontend
npm run devVisit http://localhost:5173
- User clicks "Continue with Google"
- Google OAuth flow generates JWT
- JWT + ephemeral keypair → Sui address (deterministic)
- User's keypair stored in session
- File encrypted with AES-256-GCM (symmetric key)
- Symmetric key encrypted with user's public key
- Encrypted file → uploaded to Walrus → returns CID
- Metadata (CID, encrypted key, URI) → stored on Sui
- Fetch metadata from Sui (by object ID)
- Download encrypted file from Walrus (by CID)
- Decrypt symmetric key with user's private key
- Decrypt file with symmetric key
- Download to browser
- Owner re-encrypts symmetric key with recipient's public key
- Call
add_grantee()on Sui with recipient address + re-encrypted key - Recipient can now decrypt the file
- Client-Side Encryption: Files never leave device unencrypted
- Zero-Knowledge Login: No passwords stored anywhere
- Key Derivation: User keys derived from JWT + PIN (optional)
- Access Control: On-chain verification of file ownership & sharing
- Login via zkLogin (Google)
- Upload a file (e.g.,
test.pdf) - Verify metadata on Sui Explorer
- Download the file (decrypts automatically)
- Share with another Sui address
- Recipient can download & decrypt
- React 18 + TypeScript
- Vite (build tool)
- Tailwind CSS (styling)
- @mysten/dapp-kit (Sui wallet integration)
- @mysten/zklogin (authentication)
- TweetNaCl (encryption)
- Sui Move (smart contracts)
- Walrus (decentralized storage)
walrus-vault/
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── hooks/ # Custom hooks
│ │ ├── utils/ # Encryption, Walrus, Sui utils
│ │ ├── types/ # TypeScript types
│ │ └── App.tsx
│ └── package.json
└── move/
├── sources/
│ └── walrus_vault.move
└── Move.toml
- Ensure
VITE_ZKLOGIN_CLIENT_IDis correct - Check redirect URI matches Google OAuth settings
- Clear browser cache & localStorage
- Check network (testnet/mainnet)
- Verify Walrus endpoints are reachable
- Ensure file size is within limits
- Check gas balance (
sui client gas) - Verify package ID is correct
- Check transaction on Sui Explorer
- Support multiple OAuth providers (GitHub, Discord)
- File versioning & history
- Folder organization
- Public/private file links
- File expiration (time-locked encryption)
- Mobile app (React Native)
MIT
PRs welcome! Please open an issue first to discuss changes.
Built with ❤️ on Sui + Walrus