# Network Capture Guide

How to intercept Hevy's API traffic to discover live workout endpoints.

## Strategy Priority

1. **Web app DevTools** (easiest, fastest) — Start here
2. **mitmproxy on Android** (most complete) — If DevTools insufficient
3. **APK patching** (if cert pinning blocks you)

---

## Option 1: Web App DevTools Capture (RECOMMENDED FIRST)

### Setup
```bash
# On any machine with Chrome:
# 1. Open Chrome
# 2. Go to https://hevy.com
# 3. Log in with your Hevy account
# 4. Open DevTools (F12 or Ctrl+Shift+I)
# 5. Go to Network tab
# 6. Filter: api.hevyapp.com
# 7. Check "Preserve log"
# 8. Clear existing entries (🚫 icon)
```

### Capture Workout Session
```bash
# 1. In Hevy web app, click "Start Empty Workout" or select a routine
# 2. Observe ALL network requests that fire
# 3. Complete a set (enter reps + weight)
# 4. Observe requests when saving set
# 5. Navigate to next exercise
# 6. Observe transition requests
# 7. Finish/cancel workout
# 8. Observe final requests
```

### Export
```bash
# Right-click in Network tab → "Save all as HAR with content"
# This preserves all request/response bodies
```

### Key Requests to Document

| Action | Expected Request | URL Pattern |
|--------|-----------------|-------------|
| Start workout | POST | `/workout_sessions` or `/live_workout/start` |
| Log set | POST/PUT | `/workout_sessions/{id}/sets` or `/live_workout/log_set` |
| Next exercise | PUT | `/workout_sessions/{id}` |
| Rest timer | Local only | No network call expected |
| Finish workout | POST | `/workouts` or `/live_workout/finish` |
| Cancel workout | DELETE | `/workout_sessions/{id}` |
| Poll state | GET | `/workout_sessions/active` |

---

## Option 2: mitmproxy on Ubuntu Server + Android Device

### Step 1: Install and Start mitmproxy

```bash
# Install mitmproxy
sudo apt-get update
sudo apt-get install -y mitmproxy

# Start mitmweb (web UI, easier to use)
mitmweb --listen-host 0.0.0.0 --listen-port 8080 --web-host 0.0.0.0 --web-port 8081 &

# Or start mitmproxy (terminal UI)
mitmproxy --listen-host 0.0.0.0 -p 8080

# Access web UI at: http://miopenclaw-vnic.tail9799d2.ts.net:8081/
# but Tailscale may block non-preview ports
# Use: pipo-deploy 8081 mitmweb
# Then: https://miopenclaw-vnic.tail9799d2.ts.net/preview/mitmweb/

# Access terminal UI locally:
mitmproxy -p 8080
```

### Step 2: Configure Android Proxy

On Pixel 9a:
```bash
# Settings → Network & Internet → Wi-Fi → [gear icon on current network]
# → Advanced → Proxy → Manual
# Hostname: 100.87.116.90  (Ubuntu server Tailscale IP)
# Port: 8080
# Save

# Verify proxy works:
# Open Chrome on phone → http://mitm.it
# Should show mitmproxy certificate download page
```

### Step 3: Install CA Certificate on Android

```bash
# Option A: From mitm.it (if proxy working)
# Open http://mitm.it on phone browser
# Tap Android icon → download cert
# Settings → Security → Encryption & credentials → Install a certificate
# → CA certificate → select downloaded file
# Name it "mitmproxy"

# Option B: Push cert via ADB
# Get cert from Ubuntu server:
cp ~/.mitmproxy/mitmproxy-ca-cert.cer /tmp/
adb push /tmp/mitmproxy-ca-cert.cer /sdcard/
# On phone: Settings → Security → Install from storage → select cert

# Note: Android 14+ blocks user CA certificates for apps by default!
# Only works on Android ≤13 or if app is debuggable
# Check: adb shell getprop ro.build.version.sdk
# API 34+ = Android 14+ = PROBLEM
```

### Step 4: Bypass Certificate Pinning (if needed)

```bash
# Download and patch Hevy APK
npm install -g apk-mitm

# Download APK from apkpure
wget -O hevy.apk "$(curl -s https://apkpure.com/hevy-gym-log-workout-tracker/com.hevy/download | grep -oP 'https://d\.apkpure\.com/b/APK/com\.hevy[^"]*' | head -1)"

# Patch APK (disables cert pinning, adds proxy trust)
apk-mitm hevy.apk
# Output: hevy-patched.apk

# Uninstall original Hevy (WARNING: loses local data!)
adb uninstall com.hevy

# Install patched version
adb install hevy-patched.apk

# Login again in Hevy
# Now all HTTPS traffic is interceptable
```

### Step 5: Frida Alternative (no APK modification needed)

```bash
# If APK patching fails, use Frida for runtime hooking
# Install frida-tools on Ubuntu
pip install frida-tools

# Download frida-server for Android ARM64
wget https://github.com/frida/frida/releases/latest/download/frida-server-16.x.x-android-arm64.xz
unxz frida-server-*.xz
adb push frida-server-* /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server

# Start frida-server (needs root or run-as)
adb shell /data/local/tmp/frida-server &

# Use frida to bypass cert pinning:
frida -U -f com.hevy -l ssl_pinning_bypass.js
# ssl_pinning_bypass.js can be found at:
# https://codeshare.frida.re/@pcipolloni/universal-android-ssl-pinning-bypass-with-frida/
```

---

## Option 3: Desktop Browser mitmproxy

```bash
# Simpler: capture Hevy web app traffic from desktop Chrome
# This captures the SAME web endpoints the phone app may use differently

# Start mitmproxy on Ubuntu
mitmweb --listen-port 8080 --web-port 8081 &

# On your local Chrome (not on VPS):
# 1. Settings → System → Open proxy settings
# 2. Set HTTP/HTTPS proxy to: miopenclaw-vnic.tail9799d2.ts.net:8080
#    (or use Tailscale IP 100.87.116.90:8080)

# Or use a Chrome extension like SwitchyOmega

# Install mitmproxy CA cert in Chrome:
# http://mitm.it → download cert → Chrome settings → Certificates → Import

# Browse hevy.com, start workout, observe traffic
```

---

## Capture Checklist

When capturing, record these for each request:

- [ ] Full URL (path + query params)
- [ ] HTTP method (GET/POST/PUT/DELETE)
- [ ] Request headers (especially x-api-key, auth-token, Authorization)
- [ ] Request body (full JSON)
- [ ] Response status code
- [ ] Response body (full JSON)
- [ ] Does this happen on every set? Only on start/finish?
- [ ] What triggers this request? (button tap, timer expire, auto-save)

---

## Post-Capture Analysis

```bash
# If you saved as HAR:
python3 -c "
import json
with open('hevy.har') as f:
    har = json.load(f)
for entry in har['log']['entries']:
    req = entry['request']
    print(f\"{req['method']} {req['url']}\")
"

# Extract unique endpoints:
python3 -c "
import json
with open('hevy.har') as f:
    har = json.load(f)
urls = set()
for entry in har['log']['entries']:
    u = entry['request']['url']
    # Keep only path
    from urllib.parse import urlparse
    urls.add(urlparse(u).path)
for u in sorted(urls):
    print(u)
"

# Filter to api.hevyapp.com only:
python3 -c "
import json
with open('hevy.har') as f:
    har = json.load(f)
for entry in har['log']['entries']:
    u = entry['request']['url']
    if 'api.hevyapp.com' in u:
        print(f\"{entry['request']['method']} {u}\")
"
```

---

## What to Test

During a live workout, try these scenarios:

1. **Start empty workout** (no routine) — what endpoint fires?
2. **Start from routine** — different endpoint?
3. **Log a set** (weight + reps) — what data is sent?
4. **Log multiple sets** — incremental or full state?
5. **Skip exercise** — what endpoint?
6. **Add notes to exercise** — separate endpoint?
7. **Rest timer** — network call or local only?
8. **Pause/resume workout** — any endpoint?
9. **Finish workout** — how is the completed workout sent?
10. **Cancel/discard workout** — DELETE endpoint?
11. **Force close app mid-workout** — what happens on reopen?
12. **Wear OS sync** — if you have Wear OS, capture phone-watch traffic
