Building from source
You only need this to work on the patch. To use it, install the released .mpp with Morphe instead.
The instructions assume Linux x86-64 with Python 3.12+.
Layout
| Path | Contents |
|---|---|
patches/ |
Kotlin Morphe patch (resource and bytecode hooks) |
extensions/telegram/ |
Java runtime code injected into BitChord |
vendor/tdlib-api/ |
TDLib Java bindings matching the bundled native libraries |
compile-only/ |
Stubs of BitChord/AndroidX classes, used only for compiling |
tests/, ui-tests/ |
Host tests and Robolectric tests |
checks/ |
Inspectors that run against patched APKs |
tools/ |
Release and Morphe source helpers |
The native TDLib, OpenSSL and libc++ libraries are prebuilt binaries from TGX-Android/tdlib. They aren’t compiled here. Their hashes are pinned in PROVENANCE.json.
Build and test
The simplest way to get the dependencies is from a released .mpp:
python3 tools/bootstrap_from_release.py --bundle bitchord-patches-<version>.mpp --download-tools
python3 build.py
python3 test.py
This puts the tools in .deps/tools and the native libraries in .deps/tdlib. The build output goes to build/bitchord-patches-<version>.mpp.
You can also run python3 bootstrap.py to download everything (JDK, Kotlin, Android platform, NDK, R8, Morphe Desktop and TDLib) from upstream. If you already have them, set MORPHE_TOOLS and TDLIB_ANDROID instead.
Code style
CI checks formatting. Before committing, run:
java -jar google-java-format-1.24.0-all-deps.jar --aosp --replace $(git ls-files '*.java' | grep -v '^vendor/')
java -jar ktfmt-0.53-jar-with-dependencies.jar --kotlinlang-style $(git ls-files '*.kt')
black $(git ls-files '*.py')
Android framework tests
These tests need JDK 21 and Maven 3.9+ on PATH. Maven downloads about 2 GB of dependencies.
python3 ui-tests/run.py
Checking patched APKs
Put the three original BitChord 1.8.1 APKs listed in PROVENANCE.json in a directory, then run:
ORIGINAL_APKS_DIR=/path/to/apks python3 validate_apks.py
The script patches each ABI, then checks the hooks, signatures, DEX control flow and native libraries. It needs readelf.
The hooks target the R8-optimized 1.8.1 bytecode, so small changes can break merged coroutine branches. Run this script after changing anything in TelegramPatch.kt.
New BitChord versions
The hooks are tied to the compiled code of one BitChord version, so each new version needs checking and usually some hooks updated.
The BitChord compatibility workflow (.github/workflows/bitchord-watch.yml) does the checking. Every day it looks for BitChord versions newer than app_version in PROVENANCE.json:
- a published release is tested from its APKs;
- an unreleased
vX.Y.Zbranch (BitChord develops each version on one) is built from its latest commit withassembleProdRelease, the same task BitChord’s own release workflow runs.
Branch results only mean something if a source build compiles to the same code as BitChord’s official release. To check that, run the workflow by hand with calibrate ticked: it builds the supported version from its tag and compares it class by class with the official APKs (checks/CompareDex.java). The run summary says whether every class the patch hooks is identical. Run it again whenever BitChord changes its build setup.
Each build is patched with Morphe’s version check turned off, then run through VerifyDexControlFlow and VerifyApk. The result goes to one issue per version, labelled bitchord-compat: it’s opened on the first result and commented on when the result changes. A failure names the hook that no longer matches (the TelegramPatch.kt line). A build that was already tested isn’t tested again unless you run the workflow by hand with force.
To try a BitChord APK yourself:
python3 tools/check_bitchord.py --label v1.8.2 --out build/compat path/to/BitChord-*.apk
When a version passes and works on a phone, set app_version, the original APK entries in PROVENANCE.json and the patch’s compatible versions to the new release, then follow the steps below.
Releasing
- Bump
patch_bundle_versioninPROVENANCE.json(the build scripts read it from there), updateCHANGELOG.md, then build. - Record the new MPP hash in
PROVENANCE.json(patch_bundle_sha256). -
Regenerate the Morphe source metadata:
python3 tools/prepare_mobile_source.py --bundle ../release-assets/bitchord-patches-<version>.mpp python3 tools/check_release.py --assets ../release-assets - Commit
patches-bundle.jsonandpatches-list.json. Attach the.mpp, both JSON files andSHA256SUMSto a GitHub release with the matching tag.
Morphe reads patches-bundle.json from main, and from dev when Pre-release patches is enabled.