Skip to content

rkmonarch/fidel

Repository files navigation

Fidel

A privacy-first, zero-infrastructure TOTP authenticator built with React Native (Expo) and Pear Runtime. Your 2FA secrets never touch a server — they live on your device, encrypted at rest, and will sync across your devices peer-to-peer via Autopass.

Fidel icon


Why Fidel?

Most authenticator apps make you choose between convenience (cloud backup) and privacy (local only). Fidel removes that tradeoff — your secrets stay on your device and sync directly to your other devices, with no server ever in the middle.

vs. Google Authenticator / Microsoft Authenticator

Google / Microsoft Fidel
Secret storage Synced to Google/Microsoft servers Device only, encrypted at rest
Account required Yes (Google/Microsoft account) No — zero sign-up
Vendor lock-in Lose your account → lose your codes Secrets are yours, no dependency
Open source Closed source Fully auditable
Sync Cloud (their servers) P2P direct device-to-device

vs. Authy

  • No phone number required — Authy ties your vault to a phone number; if Twilio locks your account, you're locked out. Fidel has no registration at all.
  • No proprietary server — Authy backups live on Authy's servers. Fidel syncs peer-to-peer.
  • No single point of failure — Authy going down or shutting down means you lose access. Fidel has no central service to go down.

vs. 1Password / Bitwarden TOTP

  • Free forever — 1Password requires a paid plan for TOTP. Fidel is MIT licensed with no subscription.
  • Purpose-built — password managers bolt on TOTP as a feature. Fidel is offline-first and built around authenticator UX.
  • No master password risk — your 2FA codes aren't bundled with your passwords in a single breach target.

The core difference

Most authenticators make a security vs. convenience tradeoff — no backup (risky) or cloud backup (trusts a third party). Fidel's P2P sync removes that tradeoff: multi-device, fully encrypted, zero servers.


Features

QR code scanning Scan any otpauth://totp/... QR code (Google Authenticator standard)
Manual entry Add accounts with issuer name, email, and base32 secret key
Live 6-digit codes Codes refresh every second with an animated 30-second countdown ring
Copy on tap Tap any account card to copy the current code with haptic feedback
Biometric lock Face ID or fingerprint secures the entire vault on app launch
Delete accounts Long-press any card to remove it with a confirmation prompt
Fully offline Works with no internet connection — all TOTP computation is local
P2P sync Device-to-device vault sync via Autopass (in development)

Screenshots

Home screen · Add account · Empty state onboarding


Architecture

┌─────────────────────────────────────┐
│          React Native (UI)          │
│  expo-router · TypeScript · Expo    │
│                                     │
│  useVault()   — TOTP + storage      │
│  useBiometrics() — Face ID / Touch  │
└──────────────┬──────────────────────┘
               │
   ┌───────────▼───────────┐
   │  expo-secure-store    │  ← encrypted on-device vault
   └───────────────────────┘

   ┌───────────────────────┐   (future)
   │  Bare Worklet         │
   │  Autopass · Hyperswarm│  ← P2P sync thread
   └───────────────────────┘

TOTP engine

TOTP codes are generated entirely in JavaScript with a pure-JS SHA-1 + HMAC-SHA1 implementation (RFC 6238). No native modules, no Web Crypto API dependency — it runs on any Hermes version.

Storage

Secrets are stored in expo-secure-store under a single encrypted JSON blob (fidel_accounts_v1). On iOS this uses the Keychain; on Android it uses EncryptedSharedPreferences. Secrets are stripped before they ever reach the UI layer — only { id, issuer, account, digits, period, addedAt } is returned to components.

State management

useVault() uses a module-level singleton store so all screen instances share the same live state. Adding an account in /add immediately appears on the home screen without any re-mount or navigation callback.

P2P layer (planned)

A Bare worklet running in a separate thread via react-native-bare-kit will handle Autopass/Hyperswarm P2P sync. The worklet communicates with the UI thread over a newline-delimited JSON IPC protocol. The sync layer is isolated from the core vault so the app works fully offline with zero P2P code running.


Project Structure

fidel/
├── app/                        # expo-router screens (routes only)
│   ├── _layout.tsx             # Root layout + biometric gate
│   ├── index.tsx               # Home screen — live TOTP list
│   ├── add.tsx                 # Add account (QR scanner + manual entry)
│   └── settings.tsx            # P2P sync + security settings
│
├── src/
│   ├── hooks/
│   │   ├── useVault.ts         # Core vault — TOTP engine, secure storage, state
│   │   ├── useRPC.ts           # Worklet IPC bridge (stub until P2P is wired)
│   │   └── useBiometrics.ts    # expo-local-authentication wrapper
│   ├── components/
│   │   ├── AccountCard.tsx     # TOTP card: avatar, live code, countdown ring
│   │   ├── CountdownRing.tsx   # SVG animated progress ring
│   │   ├── EmptyState.tsx      # Onboarding empty state
│   │   └── SyncStatusBadge.tsx # Peer count badge in header
│   └── theme/
│       └── index.ts            # Colors, typography, spacing, shadows
│
├── backend/
│   ├── backend.mjs             # Bare worklet source (future P2P vault)
│   └── bundle.js               # Bundled worklet (output of bundle-worklet)
│
├── assets/
│   └── images/
│       └── icon.png            # App icon
│
└── scripts/
    └── bundle-worklet.mjs      # Bare worklet bundler

Getting Started

Prerequisites

  • Node.js 18+
  • Xcode 14+ (iOS) or Android Studio (Android)
  • npx expo CLI

Install

git clone https://github.com/rkmonarch/fidel.git
cd fidel
npm install

Run on iOS Simulator

npx expo run:ios

This performs a native build on first run (a few minutes). Subsequent launches are instant — just start Metro:

npx expo start

Run on Android

npx expo run:android

Run on a physical device

Open Expo Go or a custom dev build, then scan the QR code printed by npx expo start.


Adding an Account

Via QR code

  1. Go to your service's 2FA setup page and display the QR code.
  2. Tap + in Fidel → Scan QR tab.
  3. Grant camera permission and point at the QR code — it adds automatically.

Manually

  1. In your service's 2FA setup, look for "enter key manually" or "show text key".
  2. Tap +Manual tab.
  3. Enter the service name, your account/email, and the base32 secret key.
  4. Tap Add Account.

Test key

The key JBSWY3DPEHPK3PXP is a standard RFC 6238 test vector. You can use it to verify Fidel generates the correct codes against any reference TOTP tool.


Tech Stack

Layer Technology
UI framework React Native 0.83 + Expo 55
Navigation expo-router (file-based)
Language TypeScript
TOTP RFC 6238 — pure JS SHA-1 + HMAC-SHA1
Secure storage expo-secure-store (Keychain / EncryptedSharedPreferences)
Biometrics expo-local-authentication
QR scanning expo-camera
P2P runtime react-native-bare-kit + Bare JS
P2P vault Autopass + Corestore + Hyperswarm (in development)
Icons SVG via react-native-svg
Theme Custom light design system (primary #0066FF)

Roadmap

  • Live TOTP code generation (RFC 6238)
  • QR code scanner
  • Manual account entry
  • Biometric lock (Face ID / Fingerprint)
  • Encrypted local vault (expo-secure-store)
  • Animated countdown rings
  • Copy on tap with haptics
  • P2P device sync via Autopass/Hyperswarm
  • TOTP algorithm options (SHA-256, SHA-512)
  • 8-digit code support
  • iCloud / Google Drive backup (opt-in)
  • Account grouping / search
  • Import from Google Authenticator

Contributing

Pull requests are welcome. For large changes, open an issue first to discuss what you'd like to change.

# Lint / format
npx prettier --write .

# TypeScript check
npx tsc --noEmit

License

MIT — see LICENSE.


Built by @rkmonarch · Powered by Pear Runtime / Holepunch

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors