{"id":51496828,"url":"https://github.com/oxidezap/whatspec","last_synced_at":"2026-07-07T16:01:28.195Z","repository":{"id":362680578,"uuid":"1259972515","full_name":"oxidezap/whatspec","owner":"oxidezap","description":"Extract WhatsApp Web's protocol surface from its JS bundle into a language-neutral IR (+ reference Rust). Independent; not affiliated with WhatsApp/Meta.","archived":false,"fork":false,"pushed_at":"2026-07-06T16:12:17.000Z","size":1618,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-06T16:19:38.290Z","etag":null,"topics":["codegen","intermediate-representation","oxc","protocol","reverse-engineering","rust","wasm","whatsapp","whatsapp-web"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oxidezap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T03:23:28.000Z","updated_at":"2026-07-06T15:13:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/oxidezap/whatspec","commit_stats":null,"previous_names":["oxidezap/whatspec"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oxidezap/whatspec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidezap%2Fwhatspec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidezap%2Fwhatspec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidezap%2Fwhatspec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidezap%2Fwhatspec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oxidezap","download_url":"https://codeload.github.com/oxidezap/whatspec/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidezap%2Fwhatspec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35234127,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-07T02:00:07.222Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codegen","intermediate-representation","oxc","protocol","reverse-engineering","rust","wasm","whatsapp","whatsapp-web"],"created_at":"2026-07-07T16:01:27.609Z","updated_at":"2026-07-07T16:01:28.183Z","avatar_url":"https://github.com/oxidezap.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# whatspec\n\n**Extract WhatsApp Web's protocol surface from its JavaScript bundle and emit a language-neutral IR (plus reference Rust code) — for any client/library to build on.**\n\nWhatsApp Web ships its whole protocol (IQ stanzas, protobuf schemas, GraphQL operations, app-state actions, feature flags, wire enums) compiled into a large minified JS bundle. `whatspec` parses that bundle with the [`oxc`](https://oxc.rs) AST and writes a clean, versioned, deterministic intermediate representation under [`generated/`](generated). The IR is the contract — consume it from Rust, Go, TypeScript, Python, anything. The committed Rust modules are a *reference* consumer, not the point.\n\n## What it extracts\n\n| Domain | `generated/…` | What it is |\n|---|---|---|\n| **iq** | `iq/index.json` (+ Rust) | `\u003ciq\u003e` request builders \u0026 response parsers, per namespace |\n| **proto** | `proto/WAProto.proto` | the protobuf schemas, as a `.proto` file |\n| **mex** | `mex/index.json` (+ Rust) | Relay/GraphQL persisted operations (doc id, kind, typed variables/response) |\n| **appstate** | `appstate/index.json` (+ Rust) | app-state (syncd) action schemas + indexing |\n| **abprops** | `abprops/index.json` (+ Rust) | the A/B-props feature-flag registry (~1.7k flags: code, type, default) |\n| **enums** | `enums/index.json` (+ Rust) | the wire-enum catalog (nack codes, chat/receipt types, …) |\n| **notif** | `notif/index.json` (+ Rust) | the incoming stanza-dispatch catalog: `\u003cnotification type=\"…\"\u003e` kinds + handlers + typed content shapes |\n| **tokens** | `tokens/index.json` (+ `tokens.json`) | the binary-protocol token dictionaries (single-byte + 4 double-byte), wire-indexable |\n\nEvery domain ships a JSON Schema under `generated/schema/`, and a top-level `generated/manifest.json` stamps the WhatsApp version, per-domain counts, content hashes, and extraction diagnostics.\n\n## Quick start\n\n```sh\n# Fetch the current web.whatsapp.com bundle and (re)generate everything:\ncargo run --release -p whatspec -- update\n\n# …or process bundles you already have (offline):\ncargo run --release -p whatspec -- update --bundles ./my-bundles\n\n# Version-keyed cache: skip the download when the remote version is unchanged:\ncargo run --release -p whatspec -- update --cache .wa-cache\n\n# Compare two generated outputs (e.g. across a WhatsApp version bump):\ncargo run --release -p whatspec -- diff old-generated/ generated/\n```\n\n`update` is safe by default: it refuses to overwrite the committed output if any domain's coverage shrinks (pass `--allow-shrink` to accept a genuine reduction), and fails loudly if a domain extracts nothing.\n\n## Consuming the IR\n\nThe neutral artifact is `generated/\u003cdomain\u003e/index.json`, validated by `generated/schema/\u003cdomain\u003e.schema.json`. Point your own codegen at those — the schemas are stable across WhatsApp rollouts (`schemaVersion`), independent of the ever-changing `waVersion`.\n\nA Rust consumer can instead use the committed reference modules directly; they depend only on `serde` and are tree-shakeable (you pay only for what you reference).\n\n## Design\n\n- **Deterministic:** the same bundle always produces byte-identical output (stable sort keys, no incidental ordering).\n- **C-free:** pure-Rust throughout (TLS via rustls + RustCrypto, hashing via `sha2`), enforced in CI.\n- **WASM-friendly:** the IR crate and the bundle-discovery layer compile to `wasm32`, so a browser-based fetcher can reuse them.\n\n## Disclaimer\n\n`whatspec` is an independent project and is **not affiliated with, endorsed by, or sponsored by WhatsApp LLC or Meta**. \"WhatsApp\" is a trademark of its respective owner and is used here only descriptively, to identify the protocol this tool interoperates with.\n\n## License\n\nMIT © 2025 João Lucas de Oliveira Lopes — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidezap%2Fwhatspec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foxidezap%2Fwhatspec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidezap%2Fwhatspec/lists"}