We attempted to independently reproduce the official Play Store build of Tangem Wallet v5.37.4 as part of WalletScrutiny's ongoing reproducibility monitoring.
Result: not reproducible.
This is a follow-up to our v5.36.1 finding. The same root cause applies.
What we did
- Checked out ref
v5.37.4 (commit faa8bdeaa975522b118251d4fbf9329ac41c08d1)
- Built using
./gradlew bundleGoogleRelease inside a containerized environment (Ubuntu 22.04, OpenJDK 17, Android SDK 35, NDK 25.1.8937393)
- Extracted splits via
bundletool with device-spec.json targeting arm64-v8a, API 33, xxhdpi
- Compared unpacked contents against the official Play Store split APKs
Differences found
split_config.arm64_v8a — 8 non-signing differences:
| File |
Status |
lib/arm64-v8a/libdexprotector.so |
Present in official only — absent from source build |
lib/arm64-v8a/libalice.so |
Present in official only — absent from source build |
lib/arm64-v8a/libargon2.so |
Present in both, but contents differ |
AndroidManifest.xml |
Binary diff |
base.apk — 432 non-signing differences (including AndroidManifest.xml; up from 151 in v5.36.1)
split_config.en and split_config.xxhdpi — 4 non-signing differences each (AndroidManifest.xml, resources.arsc, stamp-cert-sha256)
Key observations
DexProtector post-build transformation: libdexprotector.so is a filename associated with DexProtector (commercial bytecode protection by Licel). dexprotector-annotations.jar is present in app/libs/ in the repository. A source build produces none of these additional libraries, consistent with a post-build APK transformation step using tooling not present in the public repository.
version-control-info.textproto revision mismatch: The official base.apk contains META-INF/version-control-info.textproto with revision 3f2d7e5e16740402063a4146622be5af724381c9, which does not match the public tag commit faa8bdeaa975522b118251d4fbf9329ac41c08d1 and was not found in the public repository. This suggests the official APK was built from a commit that has not been published.
Built arm64 split unchanged: Our built split_config.arm64_v8a.apk hash is identical to our build of v5.36.1, confirming the native code in that split did not change. The official arm64 split hash did change between versions, consistent with DexProtector re-processing the APK independently for each release.
Ongoing blocker: google-services.json
The public source does not include a production com.tangem.wallet Firebase client entry in app/google-services.json. A googleRelease build requires stub injection to proceed; a fully self-contained public build remains unavailable from the published source without modification.
Request
To enable independent reproducible build verification, we would appreciate:
- Documentation of the full release build process, including any post-build transformation steps (e.g. DexProtector) applied before distribution
- Publication of the build commit used for each release, or alignment of the public tag with the actual build commit (the
version-control-info.textproto revision mismatch blocks this)
- A production-complete
google-services.json, or documentation of an alternative for community builds
We are happy to re-verify if the build process changes. Our full verification report is available on WalletScrutiny.
We attempted to independently reproduce the official Play Store build of Tangem Wallet v5.37.4 as part of WalletScrutiny's ongoing reproducibility monitoring.
Result: not reproducible.
This is a follow-up to our v5.36.1 finding. The same root cause applies.
What we did
v5.37.4(commitfaa8bdeaa975522b118251d4fbf9329ac41c08d1)./gradlew bundleGoogleReleaseinside a containerized environment (Ubuntu 22.04, OpenJDK 17, Android SDK 35, NDK 25.1.8937393)bundletoolwithdevice-spec.jsontargeting arm64-v8a, API 33, xxhdpiDifferences found
split_config.arm64_v8a— 8 non-signing differences:lib/arm64-v8a/libdexprotector.solib/arm64-v8a/libalice.solib/arm64-v8a/libargon2.soAndroidManifest.xmlbase.apk— 432 non-signing differences (includingAndroidManifest.xml; up from 151 in v5.36.1)split_config.enandsplit_config.xxhdpi— 4 non-signing differences each (AndroidManifest.xml,resources.arsc,stamp-cert-sha256)Key observations
DexProtector post-build transformation:
libdexprotector.sois a filename associated with DexProtector (commercial bytecode protection by Licel).dexprotector-annotations.jaris present inapp/libs/in the repository. A source build produces none of these additional libraries, consistent with a post-build APK transformation step using tooling not present in the public repository.version-control-info.textprotorevision mismatch: The officialbase.apkcontainsMETA-INF/version-control-info.textprotowith revision3f2d7e5e16740402063a4146622be5af724381c9, which does not match the public tag commitfaa8bdeaa975522b118251d4fbf9329ac41c08d1and was not found in the public repository. This suggests the official APK was built from a commit that has not been published.Built arm64 split unchanged: Our built
split_config.arm64_v8a.apkhash is identical to our build of v5.36.1, confirming the native code in that split did not change. The official arm64 split hash did change between versions, consistent with DexProtector re-processing the APK independently for each release.Ongoing blocker:
google-services.jsonThe public source does not include a production
com.tangem.walletFirebase client entry inapp/google-services.json. AgoogleReleasebuild requires stub injection to proceed; a fully self-contained public build remains unavailable from the published source without modification.Request
To enable independent reproducible build verification, we would appreciate:
version-control-info.textprotorevision mismatch blocks this)google-services.json, or documentation of an alternative for community buildsWe are happy to re-verify if the build process changes. Our full verification report is available on WalletScrutiny.