Self-Custodial Web3 Personal Finance
USDC Vault Manager on Base Network
Docs: Resources & Documentation
Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).
CofreAdmin is an open-source, self-custodial personal finance web application and digital dollar wallet built on the Base network (Ethereum Layer 2).
Designed with the familiarity and responsiveness of modern consumer banking apps, CofreAdmin eliminates Web3 friction: users can save in digital dollar vaults, send and receive payments, and organize their finances with human-friendly transaction memos—all while retaining 100% cryptographic self-custody over their private keys.
- 🛡️ True Self-Custody (BIP-39 + Versioned WebCrypto Vault): Wallets are generated locally using BIP-39 12-word mnemonics (
generateMnemonic+mnemonicToAccountHD derivation) and encrypted at rest with AES-GCM 256-bit powered by a non-extractable (extractable: false) IndexedDBCryptoKey(v3envelope) or PBKDF2 100k iterations (v2envelope). Servers and cloud databases never see or store your private keys or mnemonics. - 🔄 Continuous Crypto-Agility & Multi-Generation Account Upgrade Engine: Built with a forward-compatible, versioned wallet architecture (
v1→v2→v3+) that automatically detects balances from previous wallet generations on Base L2, guides a 1-click on-chain sweep to the latest cryptographic standard, and enforces mandatory recovery backup—ensuring zero fund loss across current and future security upgrades. - 💵 Digital Dollar Savings (USDC on Base): Create themed savings vaults with custom target amounts and deadlines to separate spendable funds from savings.
- ⛽ Zero-ETH Gasless Experience: Pay transaction fees directly with your USDC balance using Circle Paymaster and EIP-3009 (
TransferWithAuthorization) meta-transaction rails—no native ETH required. - 📇 Contact Book, Basenames (
.base.eth) & First-Time Recipient Protection: Save trusted contacts, resolve.base.eth(Base L2 Resolver) and.eth(ENS) names with anti-homograph spoofing protection, and receive automatic security warnings when transferring to an unfamiliar address for the first time. - ⚡ Instant Pay, Pre-Filled Payment Links & Verifiable Receipts: Scan QR codes, generate 1-click payment request links (EIP-681 + Web Deep Links) with pre-filled amounts in USDC or local currency (
R$), and share high-resolution on-chain receipt cards containing a direct BaseScan audit QR code. - 🏷️ Smart Ledger & Human Memos: Transform raw, cryptic blockchain hashes (
0x3f...) into human-readable named entries (e.g., "Groceries", "Freelance invoice") with customizable categories. - 📊 Financial Insights & PDF Export: Track daily spending pace, review category breakdowns, and export clean, accountant-ready PDF and CSV reports in one click.
- 📱 Progressive Web App (PWA): Installs directly to iOS and Android home screens as a native-feeling standalone app with offline caching and zero app store middlemen.
- Language & Runtime: TypeScript (
~5.8), Node.js (>=20) - Frontend: React 19, Vite 6, Tailwind CSS 4, Motion
- Architecture & Data Layer: Clean Architecture Repository Pattern / Service Layer (
IDatabaseService,IAuthService,IBillingServiceinsrc/services/) with hybrid Local + Cloud synchronization and 1-line database provider swapping - Web3 & Blockchain: Viem 2 (EVM / Base Network L2, BIP-39 HD Accounts, EIP-3009)
- Backend & Bundler: Express 4, esbuild
- Hosting & Cloud: (Deployable to any cloud provider; preconfigured for Firebase App Hosting)
CofreAdmin's data persistence and authentication are 100% decoupled from React UI components using the Repository Pattern (Service Layer). Zero React screens import firebase/* or access localStorage directly for business entities:
| File | Responsibility |
|---|---|
src/services/types.ts |
Strongly-typed domain models (UserProfile, Vault, Transaction, Category, SavedContact, OnChainLedgerEntry, multi-tenant userId/doctorId support) and service contracts (IDatabaseService, IAuthService, IBillingService). |
src/services/localStorageDb.ts |
LocalStorageDatabaseService — complete local/offline persistence, per-account storage isolation, transaction sanitization, and session management. |
src/services/firebaseDb.ts |
FirebaseDatabaseService & FirebaseAuthService — isolates 100% of firebase/app, firebase/auth, and firebase/firestore SDK calls, with conditional env-var initialization (isFirebaseConfigured) that safely falls back to Local Mode when .env keys are omitted. |
src/services/currentDb.ts |
HybridDatabaseService — implements IDatabaseService and IBillingService, combining instant local reads/writes with background Cloud Firestore synchronization and conflict-free merging (mergeLocalAndCloudData). |
src/services/index.ts |
Single Point of Dependency Injection exporting db, authService, and billingService. Allows switching the entire database backend (e.g., to Supabase, PostgreSQL/Cloud SQL, or REST API) by changing a single line. |
Before installing, ensure your environment meets these requirements:
- Node.js:
v20.0.0or higher (v22.xrecommended) - npm:
v10.0.0or higher - Git
Follow these steps to run a fully functional independent instance locally:
git clone https://github.com/cofreadminwallet/app.git
cd appnpm installCopy the template .env.example file to create your local .env:
cp .env.example .envnpm run devThe app will start at http://localhost:3000 with hot-reloading enabled.
npm run build
npm run startAll configuration is isolated in environment variables. Open your .env file to customize the following settings:
Firebase powers cloud database synchronization and Google Social Login. (Guest / Offline mode works 100% locally without Firebase—if VITE_FIREBASE_API_KEY is left empty, src/services/firebaseDb.ts automatically disables cloud initialization without errors and runs in Local Mode).
💡 Enabling Google Sign-In: In your Firebase Console, navigate to Authentication > Sign-in method, click Add new provider, and enable Google. No additional
GOOGLE_CLIENT_IDenvironment variable is needed—Firebase manages the authentication handshake automatically via the Firebase config variables below.
| Variable | Description | Where to find |
|---|---|---|
VITE_FIREBASE_API_KEY |
Firebase Web API Key | Firebase Console > Project Settings > Web App |
VITE_FIREBASE_AUTH_DOMAIN |
Firebase Auth domain (e.g. your-app.firebaseapp.com) |
Firebase Console > Project Settings > Web App |
VITE_FIREBASE_PROJECT_ID |
Google Cloud / Firebase Project ID | Firebase Console > Project Settings |
VITE_FIREBASE_STORAGE_BUCKET |
Firebase Storage Bucket URL | Firebase Console > Project Settings |
VITE_FIREBASE_MESSAGING_SENDER_ID |
Cloud Messaging Sender ID | Firebase Console > Project Settings |
VITE_FIREBASE_APP_ID |
Firebase Web Application ID | Firebase Console > Project Settings |
VITE_FIREBASE_DATABASE_ID |
(Optional) Named Firestore Database ID | Leave empty to use (default) |
| Variable | Description | Default / Example |
|---|---|---|
DEV_FEE_RECIPIENT_ADDRESS |
Public EVM address to receive protocol fees (0.2% fee, $0.05 min) | 0xD4875cCF... |
VITE_DEV_FEE_RECIPIENT_ADDRESS |
Client-side mirror of the fee recipient address | 0xD4875cCF... |
EXPECTED_GAS_RELAYER |
Public EVM address of designated gas relayer | 0x31b7BafB... |
VITE_EXPECTED_GAS_RELAYER |
Client-side mirror of the gas relayer address | 0x31b7BafB... |
CIRCLE_API_KEY |
(Optional) Circle developer key for paymaster operations | Leave empty for permissionless mode |
RELAYER_PRIVATE_KEY |
(Optional / Server-only) Private key if running a custom relayer | Never commit to Git |
💡 Modifying the Protocol Fee Rate: By default, outgoing transfers route a 0.2% fee (with a $0.05 USDC floor) to the
DEV_FEE_RECIPIENT_ADDRESS. To change this percentage or adjust the minimum floor, updateDEV_PROTOCOL_FEE_PERCENTandDEV_PROTOCOL_FEE_MIN_USDinsrc/services/cryptoTransferService.ts.
💡 Zero-Cost RPCs & Native USDC: Out of the box, the app connects directly to Base's official public RPC endpoint (
https://mainnet.base.org) and interacts with official native Circle USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913), requiring zero paid third-party infrastructure keys.
Enable Discord authentication under Discord Developer Portal > OAuth2:
| Variable | Description |
|---|---|
DISCORD_CLIENT_ID |
Discord Application Client ID |
DISCORD_CLIENT_SECRET |
Discord Application Client Secret |
OAUTH_STATE_SECRET |
(Optional) Server-side secret used to HMAC-sign OAuth2 anti-CSRF state tokens (auto-derived if omitted) |
Redirect URI to configure in Discord: https://<your-domain>/api/auth/discord/callback
If you are self-hosting or rebranding the application, you can customize the contact channels and support links either via environment variables or directly in the code:
| Variable | Default Value | What it Changes in the App |
|---|---|---|
VITE_SUPPORT_EMAIL |
cofreadminwallet@gmail.com |
Changes the support email linked in Settings and diagnostic mailto links |
VITE_FEEDBACK_URL |
https://forms.gle/MBpyniv5zf795wi97 |
Changes the destination of the Feedback button in Settings |
If you wish to update hardcoded default fallbacks directly in source files:
-
Database & Auth Dependency Injection Point (1-Line Provider Swap):
src/services/index.ts(db,authService,billingService) -
Repository Contracts & Domain Models:
src/services/types.ts(IDatabaseService,IAuthService,IBillingService) -
Hybrid Data Service, Cloud Firestore & Local Storage Repositories:
src/services/currentDb.ts,src/services/firebaseDb.ts, andsrc/services/localStorageDb.ts -
Support Email & Diagnostic Mailer:
src/utils/supportEmail.ts(variableSUPPORT_EMAIL) -
Feedback Link:
src/components/ProfileSettingsScreen.tsx -
Legal Terms & Documentation Link:
src/components/LegalTermsModal.tsx -
Immutable Legal Audit & LGPD Erasure Certificates:
src/services/firebaseDb.ts(logWalletBackupAcknowledgment,deleteFromCloud) andfirestore.rules -
App Version & Display Label:
src/config/version.ts(APP_VERSIONandAPP_VERSION_LABEL) -
Versioned Cryptographic Vault (
v2PBKDF2 /v3IndexedDB Non-ExtractableCryptoKey):src/utils/cryptoVault.ts(CURRENT_VAULT_ENVELOPE_VERSION,needsVaultEnvelopeUpgrade) -
Native USDC Contracts, BIP-39 Wallet Engine, Public Base RPCs & Future Generation Rotation:
src/services/web3Service.ts(BASE_USDC_MAINNET,BASE_PUBLIC_RPC,CURRENT_WALLET_GENERATION,generateMnemonicWallet,stageWalletForMigration,getPendingMigrationWallet) -
Future Protocol Key Rotation & Mandatory Backup Modals:
src/components/WalletMigrationModal.tsxandsrc/components/WalletBackupModal.tsx -
Protocol Fee Percentage & Minimum Floor (0.2% / $0.05 USDC):
src/services/cryptoTransferService.ts(constantsDEV_PROTOCOL_FEE_PERCENTandDEV_PROTOCOL_FEE_MIN_USD) -
High-Value Security Guard (Anti-Drain Cool-down Threshold):
src/components/CryptoSendModal.tsx(variableisHighValue, defaults to $\ge$100\text{ USDC}$ or$\ge \text{R$ } 500$) -
Default Budget Categories & Emojis:
src/utils/initialData.ts(arrayDEFAULT_CATEGORIES) -
Supported Fiat Currencies & Fallback Exchange Rates:
src/utils/currencies.ts(arrayTOP_CURRENCIES)
This project is 100% preconfigured for continuous deployment via Firebase App Hosting:
- Link your GitHub repository in the Firebase Console under App Hosting.
- In App Hosting > Environment settings, add the variables defined in your
.env. - The included
apphosting.yamlfile automatically handles:- Build command:
npm run build - Run command:
npm run start(serves the bundled backend on port 8080/3000)
- Build command:
- Every push to your
mainbranch triggers an automated zero-downtime build and deployment.
Because CofreAdmin compiles into a standard standalone Node.js / Express bundle (dist/server.cjs), you are not locked into Firebase. You can host it on any cloud provider, container service, or Linux VPS (Docker, Render, Railway, Fly.io, AWS, Google Cloud Run, DigitalOcean, etc.):
- Build Command:
npm run build - Run Command:
npm run start(automatically binds to the systemPORTenvironment variable)
-
Strict BIP-39 HD Key Generation (Zero Legacy Derivation): All wallets generate a cryptographically random 12-word recovery phrase (
generateMnemonic(english)) and strictly derive the exact corresponding private key and EVM address (mnemonicToAccount). Legacy deterministic seed derivation (v1) has been permanently removed from the codebase. -
Versioned Dual-Mode AES-GCM 256-bit Cryptographic Vault (
cryptoVault.ts):-
Device-Bound Non-Extractable
CryptoKey(enc:aes-gcm:idb:v3:): By default, private keys and mnemonics are encrypted with AES-GCM 256-bit (random 12-byte IV) using a masterCryptoKeygenerated withextractable: falseand stored in the browser's IndexedDB (cofreadmin_keystore_db). This ensures seamless persistence across page reloads (F5) and browser restarts while making raw key material impossible to export viaexportKey()or steal fromlocalStorage. -
PBKDF2 Passphrase & Constant-Time PIN Protection (
enc:aes-gcm:v2:): When a custom security passphrase or PIN is supplied, keys and PIN hashes are derived via PBKDF2 (100,000 iterations, SHA-256, random 16-byte salt + 12-byte IV) and verified using constant-time byte comparison (constantTimeEqual) with zero length-only fallback bypasses. -
Forward-Compatible Envelope Versioning (
v2/v3→vN): Every encrypted payload carries an explicit version prefix (CURRENT_VAULT_ENVELOPE_VERSION = 'v3') andneedsVaultEnvelopeUpgrade()detection, allowing the vault to transparently re-encrypt and upgrade key storage to future cryptographic standards (v4+) without breaking user access.
-
Device-Bound Non-Extractable
-
Zero-Overwrite & Anti-Ghost Wallet Guarantees:
- If an encrypted key is locked or fails decryption,
connectGoogleWalletimmediately halts (CARTEIRA_BLOQUEADA) and never generates or overwrites existing keys. - On cloud restore or new device login, the app always verifies local private key ownership so the displayed deposit address strictly matches a key controlled on the current device.
- Wallet resets (
resetWallet) verify on-chain Base USDC/ETH balances first and block accidental resets when funds are present.
- If an encrypted key is locked or fails decryption,
-
Universal Multi-Candidate Identity Resolution & Zero-Account-Loss Lock (
getCandidateDocIds&getStorageDataWithFallbacks):-
Exhaustive Multi-Key Candidate Sweep: To prevent account disconnections across schema or namespace updates, all user profile and wallet queries test candidate keys across all supported namespaces simultaneously:
-
Google Auth: Modern scoped prefix (
google_<sanitizedEmail>), legacy un-prefixed (<sanitizedEmail>), raw email (<email>), and auth UID (<uid>). -
Discord Auth: Modern scoped prefix (
discord_<id>), email-scoped prefix (discord_<sanitizedEmail>), legacy un-prefixed (<sanitizedEmail>), and raw numeric ID (<id>).
-
Google Auth: Modern scoped prefix (
-
Symmetric Non-Destructive Auto-Migration: When historical data is discovered under legacy or un-prefixed keys, it is seamlessly restored and mirrored to modern document collections (
userData/{docId}) and UID-backed backups (users/{uid}) usingmergeLocalAndCloudDatawith zero loss of balances, vaults, categories, or transaction histories. - First-Access Prompt Shield: If any record or wallet key is found across local storage or Cloud Firestore candidates, the "Primeiro Acesso / Novo Cadastro" screen is strictly blocked, preventing the generation of new replacement wallets over existing accounts.
-
Exhaustive Multi-Key Candidate Sweep: To prevent account disconnections across schema or namespace updates, all user profile and wallet queries test candidate keys across all supported namespaces simultaneously:
-
Future-Ready Multi-Generation Key Rotation & Upgrade Engine (
CURRENT_WALLET_GENERATION): Designed for long-term protocol evolution (v3→v4+) with zero overhead during normal operation. If a future protocol update stages a key rotation viaWeb3Service.stageWalletForMigration(),Web3Service.getPendingMigrationWallet()detects the staged previous generation wallet (cofreadmin_prev_pk_*), checks on-chain Base L2 balances, and presents the Wallet Security Upgrade modal (WalletMigrationModal.tsx) for a 1-click on-chain sweep (dynamically computing exact0.2%/$0.05protocol and$0.02gas fees) to the newly upgraded BIP-39 HD wallet, followed by mandatory recovery phrase backup. -
Strict Cloud & Storage Sanitization (
localStorageDb.ts&firebaseDb.ts): BothLocalStorageDatabaseService.saveUserandFirebaseDatabaseService.saveToCloud(viaHybridDatabaseService) explicitly stripwalletPrivateKey,walletMnemonic, andsecurityPinHashprior to serialization—sensitive key material never touches plain JSON user objects or Firestore. -
Immutable Legal & Self-Custody Audit Trail (
firebaseDb.ts&firestore.rules):-
Backup Acknowledgment Certificates (
WALLET_BACKUP_ACKNOWLEDGMENT): Whenever a user confirms having backed up their 12-word recovery phrase / private key (WalletBackupModal.tsx→db.logWalletBackupAcknowledgment), an immutable digital certificate (ack_...) is recorded with timestamps, SHA-256 hashed identifier, public wallet address, audit fingerprint, and explicit non-custodial liability acknowledgment (never storing the private key or seed phrase). -
Clickwrap Terms & LGPD/GDPR Erasure Certificates (
deleteFromCloud): First-access Privacy Policy acceptance (clickwrap_v2_...) is tracked on registration, and voluntary account deletion (db.deleteFromCloud) permanently erases active operational data while archiving an immutable erasure and self-custody audit log in compliance with LGPD Art. 16, I, II & VI (Law No. 13.709/2018). -
Write-Once Audit Rules & Dual-State Tenant Isolation: Enforced at the database level via
firestore.rules(allow update, delete: if false;on legal audit collections), guaranteeing tamper-proof evidentiary integrity, while user data collections enforce verified-email ownership across both existing (resource.data) and incoming (request.resource.data) states to prevent cross-tenant IDOR overwrites.
-
Backup Acknowledgment Certificates (
-
Client-Side Allowlist, Input Validation & Fee Guard: Outgoing meta-transactions (EIP-3009
TransferWithAuthorization) validate recipient checksums (isAddress, non-zero burn guard), positive finite amounts, total balance coverage (amount + protocolFee + gasFee <= usdcBalance), and verify the Relayer and fee recipient against an immutable client-side allowlist (capping gas fees at$0.10 USDCand protocol fees atmax(0.2%, $0.05 USDC)prior to signing). -
Cryptographic EIP-3009 Nonces: All transaction authorization nonces are generated with
crypto.getRandomValues(32)to eliminate predictable nonce collision attacks. -
Zero Secrets in Code, Resilient Env-Var Config & Strict
.gitignore: Zero API keys, Firebase credentials, database passwords, or private keys are hardcoded in the repository (src/services/firebaseDb.tsreads exclusively fromimport.meta.env.VITE_FIREBASE_*). Files matching.env*,*.key,bun.lock*,service-account*.json, and private metadata are strictly excluded from commits, and any auto-generated local development relayer key (.relayer.dev.key) is created with strict0600owner-only file permissions. -
OAuth2 Anti-CSRF, XSS & Origin Hardening: Discord OAuth2 flows enforce one-time HMAC-SHA256 signed
statetokens verified withcrypto.timingSafeEqual(10-minute TTL and replay eviction), strictHost/X-Forwarded-Hostheader allowlist validation, HTML/JSON script-context escaping (escapeHtml/safeJsonForScript), and exactwindow.location.origintarget origin verification on popuppostMessagehandshakes. -
Hardened Web3 Relayer & Paymaster Security (
/api/paymaster/transfer&/api/paymaster/proxy):-
Pre-Flight EIP-712 Signature & On-Chain Nonce Validation: Before spending any Relayer ETH gas, the server cryptographically verifies all three EIP-3009 ECDSA signatures (
recoverTypedDataAddressfor main transfer, protocol fee, and gas fee), enforces server-side fee floors ($0.02 USDCgas fee and0.2%/$0.05 USDCprotocol fee), and checks on-chainauthorizationStateand totalbalanceOf(from)on Base L2. -
Serialized Relayer Mutex & Dual Rate Limiting: A server-side execution mutex (
withRelayerExecutionLock) and per-sender concurrency lock prevent EVM nonce collisions and double-spend TOCTOU races, paired with dual per-IP (trust proxysingle-hop) and per-wallet rate limiting. -
Fail-Closed Paymaster RPC Proxy:
/api/paymaster/proxyblocks JSON-RPC batch arrays and enforces a fail-closed contract allowlist (BASE_USDC_ADDRESSandALLOWED_PAYMASTER_CONTRACTS) forpm_sponsorUserOperation/pm_getPaymasterStubDatacalls.
-
Pre-Flight EIP-712 Signature & On-Chain Nonce Validation: Before spending any Relayer ETH gas, the server cryptographically verifies all three EIP-3009 ECDSA signatures (
-
CSV Formula Injection Prevention: Financial statement exports (
pdfService.ts) automatically neutralize spreadsheet formula triggers (=,+,-,@,\t,\r) and escape embedded quotes before generating CSV files, preventing DDE/macro execution in Excel, LibreOffice, and Google Sheets. -
Web Security & Auth Proxy Hardening: The Express backend implements OWASP defense headers (
X-Content-Type-Options: nosniff,X-Frame-Options: SAMEORIGIN,X-XSS-Protection,Referrer-Policy: strict-origin-when-cross-origin) and strict path/SSRF validation on/__/auth/*reverse-proxy routes.
In compliance with the AGPL-3.0-or-later terms:
- Official Support Email: cofreadminwallet@gmail.com
- Official Discord:
@cofreadmin - Official Feedback Form: Submit Feedback
- Documentation & Resources: GitHub Docs Repository
- Product Lifecycle & UX Flow:
GitHub Docs Repository/.. product-flow.md
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
See the LICENSE.md file for full details.
💖 Donate Support the development:
- Fiat: GitHub Sponsors
- Crypto: BTC/USDC/ETH/SOL