A blockchain-based password manager that provides secure, decentralized storage for encrypted credentials using smart contracts and client-side encryption.
Keyvault consists of three main components that work together to provide a complete password management solution:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Browser │ │ Frontend │ │ Smart Contract │
│ Extension │───▶│ (React App) │───▶│ (Blockchain) │
│ │ │ │ │ │
│ • Encrypt/ │ │ • Wallet │ │ • Store │
│ Decrypt │ │ Integration │ │ Encrypted │
│ • UI/UX │ │ • Transaction │ │ Data │
│ • Local Storage │ │ Management │ │ • Public Keys │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- Browser Extension → Frontend: Sends encrypted credential data via postMessage API
- Frontend → Smart Contract: Submits encrypted data to blockchain via wallet transactions
- Smart Contract: Stores encrypted blobs and public keys on-chain with append-only structure
| Network | Address | Explorer |
|---|---|---|
| Astar | 0x3afe36158bBA43715b22ECfeFa530f0981FAC9C0 |
Blockscout |
| Base | 0x4DecB055bC80Ad00098A2CDda4E2c76b546E9403 |
Basescan |
| Localhost | 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 |
- |
- Node.js 18+ and bun
- Foundry for local blockchain
- MetaMask or compatible Web3 wallet
- Firefox Developer Edition (for Firefox users) or Chromium-based browser (Chrome, Brave, etc.)
-
Clone and setup:
git clone https://github.com/lousydropout/keyvault.git cd keyvault -
Start local blockchain (Terminal 1):
cd contract bun install bun run local:node -
Deploy smart contract (Terminal 2):
cd contract bun run local:deploy # Note the deployed address
-
Start frontend (Terminal 3):
cd frontend bun install bun run dev -
Install browser extension:
cd browser-extension bun install bun dev # Load the extension in your browser (see browser-extension/README.md)
- Frontend: Access the deployed frontend at your production URL
- Network: Ensure wallet is connected to Astar network
- Extension: Load the production build of the browser extension
/contract- Hardhat project containing the Keyvault smart contract/frontend- React application for Web3 interactions and UI/browser-extension- Browser extension for credential management and encryption
Keyvault provides a blockchain-based solution for securely storing, managing, and accessing encrypted credentials. It leverages blockchain's inherent security features (transparency, immutability, tamper resistance) while maintaining user privacy through client-side encryption.
- Client-Side Encryption: All encryption/decryption occurs in the browser extension using AES-GCM
- Append-Only Storage: Prevents race conditions and ensures data consistency across devices
- Public Key Infrastructure: Enables secure sharing of credentials between users
- Wallet-Based Authentication: Uses blockchain wallet signatures for access control
Keyvault stores credentials as encrypted JSON objects with the following structure:
{
"version": 1,
"type": 0,
"id": "<unique_credential_id>",
"timestamp": "<last_updated_timestamp>",
"isDeleted": false,
"url": "<website_url>",
"username": "<username>",
"password": "<password>",
"description": "<optional_description>"
}{
"version": 1,
"type": 0,
"id": "<unique_credential_id>",
"timestamp": "<deletion_timestamp>",
"isDeleted": true,
"url": "<website_url>"
}The system also supports:
- Keypair Credentials (
type: 1): For storing cryptographic key pairs - Secret Share Credentials (
type: 2): For Shamir's Secret Sharing - Contact Credentials (
type: 3): For storing contact information
id: A unique identifier (generated usingcrypto.getRandomValues()) that remains constant across all versions of a credentialtimestamp: Used to order versions chronologically within a credential chain- Credential Chains: All versions of a credential share the same
id, forming a chronological chain of updates - New Credentials: Get a new randomly generated
id - Updated Credentials: Keep the same
idbut get a newtimestamp - Deleted Credentials: Create a deletion record with the same
idandisDeleted: true
### Storage Process
1. **Compression**: Credentials are shortened using the `createKeyShortener` utility, which converts objects to compact arrays by removing keys and trimming trailing null/undefined values
2. **Bundling**: Multiple shortened credentials are bundled together into arrays
3. **Serialization**: Bundles are serialized using MessagePack for efficient binary encoding
4. **Encryption**: Serialized bundles are encrypted using AES-GCM with unique initialization vectors (IVs)
5. **On-Chain Storage**: Encrypted blobs are stored as base64-encoded strings in the smart contract's `entries` mapping
### Append-Only Model
This design ensures:
- **Immutability**: Complete audit trail of all credential changes
- **Consistency**: No race conditions when accessing from multiple devices
- **Traceability**: Full history of credential lifecycle
- **Chain Integrity**: Credentials with the same `id` form chronological chains, allowing reconstruction of complete credential history
## Encryption Details
### Algorithm: AES-GCM
- **Security**: Strong encryption with built-in authentication
- **Performance**: Efficient for both encryption and decryption
- **IV Requirement**: Each operation uses a unique Initialization Vector
- **Format**: Stored as `iv + ciphertext` concatenated string
### Why AES-GCM?
- Industry-standard encryption with proven security
- Provides both confidentiality and integrity protection
- Efficient performance for web applications
- Wide browser support for WebCrypto API
## Network Support
### Supported Networks
- **Localhost** (Chain ID: 31337): Hardhat development network
- **Shibuya** (Chain ID: 81): Astar testnet (contract deployment only)
- **Astar** (Chain ID: 592): Production mainnet
- **Base** (Chain ID: 8453): Production mainnet
**Note**: Frontend and browser extension support localhost, Astar, and Base. Shibuya support is available for contract deployment but not in the frontend interface.
### Network Configuration
- Chain selection is handled dynamically at runtime via the extension's chain selector
- Smart contract addresses are configured in `CHAIN_CONFIGS` and automatically selected per network
- Wallet network switching is handled through the UI
## Development Commands
### Contract Development
```bash
cd contract
bun run local:node # Start local blockchain
bun run local:deploy # Deploy to localhost
bun run hardhat console # Interactive contract debugging
cd frontend
bun run dev # Development server
bun run build # Production build
bun run lint # Code lintingcd browser-extension
bun dev # Build extension for both Firefox and Chromium
bun test # Run test suiteImportant: This monorepo uses different test runners for different components:
- Browser Extension: Uses Bun's built-in test runner (unit tests)
- Frontend: Uses Vitest with jsdom (React component tests)
Running Tests:
# From root - runs all tests with appropriate runners
bun run test
# Or run tests individually:
cd browser-extension && bun test # Browser extension tests
cd frontend && bun run test # Frontend tests (uses vitest)
# Note: Running `bun test` at root will discover all test files
# but frontend tests will fail because they need jsdom.
# Always use `bun run test` from root instead.Contract deployment address mismatch:
- Check deployed address with:
bun hardhat ignition status localhost-london - Update
frontend/src/localKeyvaultAddress.tsif needed
Extension communication failures:
- Verify extension is loaded and active
- Check browser console for postMessage errors
- Ensure frontend origin matches extension permissions
Wallet connection issues:
- Confirm MetaMask is installed and unlocked
- Verify correct network selection (localhost/Astar)
- Check wallet permissions for the application
Transaction failures:
- Ensure sufficient gas/tokens for transactions
- Verify contract address is correct for the network
- Check wallet nonce synchronization
This repository represents a refactor from an earlier ink!-based implementation. The conversion to Solidity was made to improve block explorer compatibility and verification capabilities.
Previous repositories:
- password-manager - Frontend and ink! smart contract
- password-manager-extension - Chrome extension
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
This project is supported by Astar's Unstoppable Community Grant program. See UCG Overview for details.
- 3rd Place - Polkadot ink! Hackathon (Oct/Nov 2023) - Most Innovative ink! dApp
- Honorable Mention - Best projects using ink!athon or AZERO.ID
Special thanks to Astar's Sofiya Vasylyeva for ongoing mentorship and support throughout the development process.
For more details about the hackathon, see Tina Bregović's write-up: Polkadot ink! Hackathon powered by Encode Club—Prizewinners and Summary.