Skip to content

Commit 70e106f

Browse files
committed
Add docs and link from README
1 parent 84ba71e commit 70e106f

6 files changed

Lines changed: 156 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ or a ready-to-use subscription link.
2525
| **iOS** | Sideload the `.ipa` from [**Releases**](../../releases/latest) (AltStore · Sideloadly · TrollStore) |
2626
| **Web** | Open the console → [**useruserdev.github.io/happwn**](https://useruserdev.github.io/happwn/) |
2727
| **Subscription** | Deploy your own free Cloudflare [**Worker**](worker/README.md), paste its URL in Settings |
28+
| **Docs** | Guides & reference → [**docs/**](docs/) |
2829

2930
<br>
3031

docs/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# happwn docs
2+
3+
happwn decrypts Happ `happ://` links and turns the configs into something you can use —
4+
an iOS app, a web console, or a hosted subscription URL. Everything decrypts on-device.
5+
6+
## Contents
7+
8+
- [iOS app](ios.md) — install the sideloaded `.ipa`, settings, how it builds
9+
- [Web console](web.md) — browser decrypt, manual extraction
10+
- [Subscription Worker](../worker/README.md) — deploy your own Cloudflare Worker
11+
- [How decryption works](crypto.md) — schemes, crypto, keys
12+
- [FAQ & troubleshooting](faq.md)
13+
14+
## At a glance
15+
16+
```
17+
happ://crypt… ──decrypt──▶ subscription URL
18+
│ GET with User-Agent + X-HWID
19+
20+
configs (vless / vmess / trojan / …)
21+
```
22+
23+
The subscription server rejects requests that don't carry the Happ `User-Agent` and your
24+
`X-HWID`, so those are set in Settings (app or web).

docs/crypto.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# How decryption works
2+
3+
`happ://` links are encrypted; happwn reverses the scheme entirely on-device.
4+
5+
| Scheme | Pipeline |
6+
| ------ | -------- |
7+
| `crypt` · `crypt2` · `crypt3` · `crypt4` | base64 → RSA PKCS#1 v1.5 |
8+
| `crypt5` | CDAB permutation → RSA key recovery → ChaCha20-Poly1305 → base64 |
9+
10+
The decrypted payload is usually a **subscription URL**. Fetching it with the Happ
11+
`User-Agent` + `X-HWID` returns the actual configs (`vless`, `vmess`, `trojan`, `ss`,
12+
`ssr`, `hysteria2`, `tuic`, `wireguard`).
13+
14+
## Two implementations, one result
15+
16+
| Platform | Crypto |
17+
| -------- | ------ |
18+
| iOS | Rust core (`rsa`, `chacha20poly1305`, `base64`) shipped as a static `.xcframework` |
19+
| Web | JavaScript (`node-forge` for RSA, `@noble/ciphers` for ChaCha20-Poly1305) |
20+
21+
Both embed the same keys and produce identical output. CI verifies each against the same
22+
real `crypt4` and `crypt5` vectors on every push, so the two implementations can't drift.
23+
24+
## Keys
25+
26+
The RSA keys (4 PKCS#1 keys for `crypt``crypt4`, 34 marker-indexed PKCS#8 keys for
27+
`crypt5`) are bundled with the app and site — they are what makes offline decryption
28+
possible. They live in `rust/data/` (iOS) and `web/` (browser).

docs/faq.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# FAQ & troubleshooting
2+
3+
**“Server rejected — check User-Agent and X-HWID”**
4+
The subscription server requires the exact Happ `User-Agent` and your device's `X-HWID`.
5+
Set both in Settings and try again.
6+
7+
**A client shows “App not supported”**
8+
That client has no HWID support, so it can't load the link directly. Use happwn (app or
9+
web) to decrypt and pull the configs, or run the manual `curl` command from
10+
[web.md](web.md#manual-extraction-no-worker).
11+
12+
**“Decrypt failed”**
13+
The link isn't a supported `happ://` scheme (`crypt``crypt5`) or it's malformed/truncated.
14+
Copy the full link again.
15+
16+
**Web: “Forge failed” / network error**
17+
Your `Worker URL` isn't set, or the Worker can't reach the subscription server. Confirm
18+
the Worker is deployed with the `SUBS` KV binding and the URL is pasted in Settings.
19+
See [worker/README.md](../worker/README.md).
20+
21+
**Nothing parsed — only a raw response**
22+
The server returned something that isn't a recognized config list. The raw body is shown
23+
so you can inspect it; the link or your headers may be wrong.
24+
25+
**Is my data private?**
26+
Decryption happens on your device. The web subscription is stored in **your own**
27+
Cloudflare KV under a random, unguessable token (7-day expiry). Nothing is sent to us.

docs/ios.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# iOS app
2+
3+
A config extractor, distributed as an unsigned `.ipa` and sideloaded — no App Store.
4+
5+
## Install
6+
7+
1. Download the latest `happwn-*.ipa` from [Releases](../../../releases/latest).
8+
2. Sideload it with **AltStore**, **Sideloadly**, or **TrollStore**.
9+
3. Open the app → **Settings** → set your `User-Agent` and `X-HWID`.
10+
4. Paste a `happ://` link and tap **Extract**.
11+
12+
## Using it
13+
14+
- Paste a `happ://crypt…` link → the app decrypts it and follows the embedded
15+
subscription URL using your `User-Agent` + `X-HWID`.
16+
- The configs (`vless`, `vmess`, `trojan`, `ss`, …) are listed — tap to copy one,
17+
copy all, share, or export.
18+
- If a server returns nothing recognizable, the raw response is shown for inspection.
19+
20+
## Settings
21+
22+
| Field | Meaning |
23+
| ----- | ------- |
24+
| `User-Agent` | The value the subscription server expects (e.g. `Happ/x.y`). |
25+
| `X-HWID` | Your device id; the server binds the subscription to it. |
26+
27+
Both are stored locally on the device only.
28+
29+
## How it builds
30+
31+
CI on GitHub Actions (macOS) compiles the Rust crypto core into an `.xcframework`,
32+
builds the SwiftUI app, runs the tests, and publishes a versioned unsigned `.ipa` to
33+
Releases on every push to `main`. No Mac required to get a build.
34+
35+
Local build (macOS):
36+
37+
```bash
38+
bash scripts/build-xcframework.sh
39+
cd ios && xcodegen generate && open happwn.xcodeproj
40+
```

docs/web.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Web console
2+
3+
**https://useruserdev.github.io/happwn/**
4+
5+
Decrypts `happ://` links right in the browser — nothing leaves your device. Decryption
6+
needs no setup. To turn the configs into a subscription URL, deploy your own Worker.
7+
8+
## Flow
9+
10+
1. Paste a `happ://` link → **Decrypt** (runs locally). The decrypted value (usually a
11+
subscription URL) appears with a copy button.
12+
2. **Forge subscription** → sends the URL to your Worker, which fetches it with the right
13+
headers and returns a hosted `…workers.dev/sub/<token>` link, with a QR and the
14+
config list.
15+
16+
Settings (gear): `User-Agent`, `X-HWID`, and your `Worker URL` — all stored in the
17+
browser's localStorage.
18+
19+
## Why a Worker is needed
20+
21+
A browser **cannot** set the `User-Agent` header (it's a forbidden header) and is blocked
22+
by **CORS** from fetching the subscription server directly. So the authenticated fetch
23+
runs server-side on a small Cloudflare Worker that you deploy and own. Setup:
24+
[worker/README.md](../worker/README.md).
25+
26+
## Manual extraction (no Worker)
27+
28+
When a client shows **“App not supported”** (it lacks HWID support), pull the configs
29+
yourself in a terminal:
30+
31+
```bash
32+
curl -fsSL -H "User-Agent: Happ/1.0" -H "X-HWID: <your-hwid>" "<sub-url>" | base64 -d
33+
```
34+
35+
The web console builds this exact command for you from the decrypted link and your
36+
settings — just copy it.

0 commit comments

Comments
 (0)