# DebridStream v3 (Native Kotlin/Compose) — Architecture & Analysis

**Version:** v3.4.1 (June 2026)
**Package:** `com.debridstream.tv`
**Framework:** Native Kotlin/Compose (single-activity)
**Obfuscation:** Heavy ProGuard + R8 (single-letter packages)
**APK Size:** 27MB

## Architecture Overview

The app is a **stateless scraper shell** — it has no proprietary backend server. All content is driven by third-party APIs and public GitHub configs.

```
User → DebridStream App
         ↓ Firebase Auth (Google Sign-In)
         ↓ Firestore: debridKeys/{uid} (user's provider tokens)
         ↓ Third-party APIs (Trakt, TMDB, Real-Debrid, TorBox, AllDebrid, OpenSubtitles)
         ↓ GitHub Configs (content catalogs, filter rules)
```

## Backend: Firebase Only

| Service | Detail |
|---|---|
| **Firebase Auth** | Google Sign-In |
| **Firestore collections** | `debridKeys` (provider tokens), `accountSync` (user config), `catalogs` (custom lists) |
| **Crashlytics** | Firebase Crashlytics |
| **Firebase Storage** | `debridstream-93a0b.firebasestorage.app` |
| **API key** | `AIzaSy...wl8E` (SHA-1 locked to `com.debridstream.tv`) |

## Key Security Findings

| Finding | Severity |
|---|---|
| RevenueCat subscription client-side only (check patched) | 🔴 Critical |
| RevenueCat API key exposed (`goog_sWsTsDsNGSaudOdjvfjBZriZDkK`) | ⚠️ Low (public SDK key) |
| TMDB API key exposed (`7ba07eac0fde9485edfc077df9937ab6`) | ⚠️ Low (free, rate-limited) |
| Firestore locked (no public access, key SHA-1 restricted) | ✅ Secure |
| allowBackup=true | ⚠️ Low (adb backup possible) |
| No SSL pinning | ⚠️ Medium |

## External API Surface

### Debrid Providers
- **Real-Debrid:** `api.real-debrid.com/rest/1.0` (addMagnet, torrents, unrestrict)
- **TorBox:** `api.torbox.app/v1/api` (checkcached, createtorrent, mylist, requestdl, user/me)
- **AllDebrid:** `api.alldebrid.com/v4`, `api.alldebrid.com/v4.1`
- **Premiumize:** (identified in code)
- **OffCloud:** (identified in code)

### Media Metadata
- **TMDB:** `api.themoviedb.org/3/` (discover, search, movie, tv — key: `7ba07eac0fde9485edfc077df9937ab6`)
- **Trakt:** `api.trakt.tv/` (OAuth, scrobble, search, sync, calendars, oauth/device)
- **OpenSubtitles:** `api.opensubtitles.com/api/v1` + Stremio proxy `opensubtitles-v3.strem.io`

### Content Config (GitHub)
- **Config:** `raw.githubusercontent.com/lawdev-cmd/map/main/config.json` (filters, emergency message)
- **Entry Map:** `same repo/entryMap.json` (IMDB ID corrections)
- **Catalogs:** `raw.githubusercontent.com/lawdev-cmd/pub/main/` (home.json, movie.json, tv.json, collections-main.json + genre collections)

### Other
- **Intro detection:** `api.introdb.app/intro?imdb_id=`
- **TMDB images:** `image.tmdb.org/t/p/w200|w500|w780|w1280`

## RevenueCat Subscription Bypass

The subscription check is in `V2/y0.smali` (jadx name: `V2/C0741y0.java`), method `g()`:

```java
// Original (obfuscated):
zContainsKey = ((CustomerInfo) obj).getEntitlements().getActive().containsKey("pro");

// Patched SMALI:
const/4 p1, 0x1  // always true
```

**Both paths patched:**
1. Normal flow: skip RevenueCat call, return `true`
2. Catch block: `const/4 p1, 0x0` → `const/4 p1, 0x1` (returns true on error too)

See `references/smali-patching-subscription-bypass.md` for the full workflow.

## Version History

| Version | Framework | Size | Obfuscation | Notes |
|---|---|---|---|---|
| v2.0.0 (Nov 2025) | React Native / Expo | 158MB | ProGuard on Java shell + minified JS | Business logic in JS bundle |
| v3beta (Mar 2026) | Native Kotlin/Compose | ? | Heavy ProGuard+R8 | First native rewrite |
| v3.2.3 (May 2026) | Native Kotlin/Compose | 21MB | Heavy ProGuard+R8 | Same architecture as v3.4.1 |
| v3.4.1 (Jun 2026) | Native Kotlin/Compose | 27MB | Heavy ProGuard+R8 | Latest, FFmpeg + Dolby Vision |
