Skip to content

Repository files navigation

Custos Mobile

A React Native (Expo) crime-evidence recorder for the Custos Diretriz platform. It captures video/photo, pins it to IPFS, and anchors the hash on-chain — reusing the existing dapp's hosted API and smart contracts.

Its flagship feature is the Hidden Guardian: triple-press the power button on Android to start a silent background recording — no preview, no need to open the app.

How it works

capture (in-app camera OR hidden service)
   → pin to IPFS (Pinata)
   → POST /api/guest-save on the hosted dapp (server signs as guest recorder)
   → evidence hash anchored on-chain (Celo / Starknet)

Anything that can't reach the network is stored locally and retried automatically on next launch (src/lib/pipeline.ts), mirroring the dapp's emergency-save behaviour. No funded wallet is needed on the device — the hosted backend signs guest records.

The Hidden Guardian (power-button trigger)

Android iOS
Trigger Power button ×3 Volume button ×3 (Apple blocks power-button interception)
Records with screen off / app closed ✅ background foreground-service ❌ not allowed by iOS
Preview shown None (hidden) In-app camera opens (foreground)
Notification Required by Android while recording n/a

Android (modules/hidden-recorder): a foreground Service (HiddenCameraService.kt) registers for SCREEN_ON/SCREEN_OFF broadcasts. Each power press toggles the screen once; 3 toggles within 2s fire a recording. It records via CameraX VideoCapture with no preview surface, saves an mp4 to app-private storage, and emits the file URI to JS, which runs the upload pipeline. Android law requires a persistent notification while a camera/mic foreground service runs — "hidden" means no camera preview, not an invisible process.

iOS (HiddenRecorderModule.swift): Apple does not allow apps to intercept the power/side button or record the camera in the background. The fallback is a rapid volume-button gesture (KVO on the audio session's output volume) that opens the in-app recorder.

Tuning

When calling enableTrigger({ pressCount, windowMs, maxDurationMs }) (src/lib/hiddenRecorder.ts):

  • pressCount — presses to trigger (default 3)
  • windowMs — max time for the gesture (default 2000)
  • maxDurationMs — auto-stop after this long (default 60000)

Setup

cp .env.example .env      # add EXPO_PUBLIC_PINATA_JWT (same as the dapp's NEXT_PUBLIC_IPFS_KEY)
npm install

Run

The native Hidden Guardian module is not in Expo Go — you need a dev/production build:

# Android (device or emulator + Android SDK)
npx expo run:android

# iOS (macOS + Xcode)
npx expo run:ios

# or a cloud build with EAS
npx eas build --profile development --platform android

expo run:* regenerates the native projects from app.json (the android/ and ios/ folders are git-ignored — this is Continuous Native Generation). The config plugin plugins/withHiddenRecorder.js injects the foreground <service> and its foregroundServiceType.

For the JS-only screens you can still use Expo Go (npx expo start), but the Guardian toggle will report "native build required".

Project layout

src/app/            expo-router screens: index, record, evidence, settings
src/lib/
  config.ts         API base URL, Pinata JWT, IPFS gateway
  chains.ts         chain registry + CrimeRecord ABI (ported from the dapp)
  ipfs.ts           pin a local file to IPFS via Pinata
  evidence.ts       anchor on-chain via hosted /api/guest-save; read evidence
  pipeline.ts       secureEvidence() + offline retry queue + local history
  hiddenRecorder.ts JS bridge to the native module (degrades safely)
modules/hidden-recorder/   local Expo native module (Kotlin + Swift)
plugins/withHiddenRecorder.js   config plugin (Android manifest service)

Permissions

Camera and microphone are requested in-app. On Android 13+ the OS also asks for notification permission (the foreground-service notification). Everything is declared in app.json.

Consent & legality

Recording laws vary by jurisdiction — some require consent to record audio or in private spaces. Users are responsible for lawful use. On-chain anchoring makes evidence timestamped and tamper-evident; it is not legal advice.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages