This app was first launched on 1st November 2018 and currently has more than 10000 downloads, a 4.1 stars rating from 332 users and the latest APK (version 4.9.4) was from 22nd January 2020 and is newer than the below reviewed version of the app.
Our analysis was done on 8th January 2020 based on data found in their Playstore description and their website and their source repository. We discuss the issue with verification with the provider here.
We found these ways of contacting the developers:
- Review of version 4.8.1 on 14th December 2019 (verdict: nonverifiable)
Help spread awareness for build verifiability
Please help us spread the word, asking BlueWallet Bitcoin Wallet to support verifiable builds via their Twitter!
The following Analysis is not a full code review! We plan to make code reviews available in the future but even then it will never be a stamp of approval but rather a list of incidents and bad coding practice. We cannot find and tell you all the dark secrets the wallet providers might have.
Do your own research!
Try out searching for "lost bitcoins", "stole my money" or "scammers" together with the wallet's name, even if you think the wallet is generally trustworthy. For all the bigger wallets you will find accusations. Make sure you understand why they were made and if you are comfortable with the provider's reaction.
Blue Wallet was not verifiable before but the team suggested it might work with some added build instructions in this issue. Lets see …
The current version is
$ git clone https://github.com/BlueWallet/BlueWallet.git $ cd BlueWallet/ $ git tag | grep 4.9 v4.9.0
There is no
4.9.1. Not good.
$ git checkout master $ git log --oneline -n 50 7e8c216 (HEAD -> master, origin/master, origin/HEAD) ADD: CLP Fiat 4078ed3 REF: electrum ccd6602 Merge pull request #789 from BlueWallet/swipee2 78e82a8 Update deepLinkSchemaMatch.test.js 347c256 Merge branch 'master' into swipee2 2ec19bd REF: SelectWallet uses Hooks e900e6e Updated to make docs to make it more precise 8889d5d updating instructions for console compilation 24a3259 OPS: Package updates 1e4b655 ADD: Tests for DeeplinkSchemaMatch 16ecd30 ADD: Swipe to Scan 847bfef Update Android build instructions 951034f ADD: Lock App to Portrait mode 3dd50f8 FIX: Don't show wallet export warning if wallet was imported. bae0c09 Add "engines" field to package.json 4903eb2 update readme 3678c37 FIX: Set isLoading to false when biometrics unlock fails adf00f1 TST: fix selftest 6dac734 FIX: TX Time visual glitch 89e1518 TST: simplify 51e0d7d REF: BIP49 to use electrum c975347 REF: Reworked Import wallet flow ec5bc4a ADD: Ask user if they have backed up their seed phrase 29d35c3 ADD: Export screen allows copying to clipboard if its a LNDHub wallet c2eb13d ADD: Show LNDHub backup when creating lnd wallet cd7526d OPS: fix appcenter android build 5d569f8 REF: Default view settings now uses Hooks b9e223a REF: Release Notes uses Hooks 6a5d9da REF: About now uses hooks bbe01d1 FIX: TX list uses whole canvas area ea23dc1 FIX: Show an alert when theres a fetch transactions error. be8cfc3 OPS: post APK link in PRs b341f8b FIX: Receive address was not being rendered 183135d FIX: Wallet type selecion clipping on advanced mode 775d4be FIX: Wallet type selecion clipping on advanced mode d75ce20 Merge branch 'master' of github.com:BlueWallet/BlueWallet 664c3a5 TST: muted some tests because blockchain.info api started to return incomplete data (not the first time their API breaks); muted till I rewrite BIP44 to electrum b1748b8 FIX: Issue 769. Don't allow empty wallet labels b30656e REF: Custom receive 5f50be2 ADD: Handle clipboard content with both bitcoin: and lightning: 8bce843 REL: ver bum[ d764ede (tag: v4.9.0) REL: rel notes ed944e7 REL: ver bump f077f89 FIX: scan QR with mnemonics now defaults to BIP84 if wallet is blank 703196d Revert "FIX: Dismiss modal after success import" bdb9add ADD: Native segwit as default wallet f8fa0ad ADD: Hide Manage Funds button if wallet doesn't allow onchain refill. 5ad850e ADD: Scroll to end of wallets list when adding a wallet 67bdd84 TST: someone ACTUALLY used this example mnemonic lol. fixed fc3bb6f FIX: Scan to receive is more visible
none of those looks like it might be the version we are looking for. We still try out the build instructions assuming the latest commit to be our best guess:
$ docker run -it --volume $PWD:/mnt --workdir /mnt --rm beevelop/cordova bash root@93d42b33d091:/mnt# npm install root@93d42b33d091:/mnt# cd android/ root@9b73bbcbb500:/mnt/android# yes | /opt/android/tools/bin/sdkmanager "build-tools;28.0.3" root@93d42b33d091:/mnt/android# ./gradlew clean assembleRelease
but this also didn’t succeed:
* What went wrong: Execution failed for task ':@remobile_react-native-qrcode-local-image:verifyReleaseResources'. > 1 exception was raised by workers: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource linking failed error: resource android:style/TextAppearance.Material.Widget.Button.Borderless.Colored not found. error: resource android:style/TextAppearance.Material.Widget.Button.Colored not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values-v26/values-v26.xml:7: error: resource android:attr/colorError not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values-v26/values-v26.xml:11: error: resource android:attr/colorError not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values-v26/values-v26.xml:15: error: style attribute 'android:attr/keyboardNavigationCluster' not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values-v28/values-v28.xml:7: error: resource android:attr/dialogCornerRadius not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values-v28/values-v28.xml:11: error: resource android:attr/dialogCornerRadius not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2734: error: resource android:attr/fontStyle not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2735: error: resource android:attr/font not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2736: error: resource android:attr/fontWeight not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2737: error: resource android:attr/fontVariationSettings not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2738: error: resource android:attr/ttcIndex not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2902: error: resource android:attr/startX not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2905: error: resource android:attr/startY not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2908: error: resource android:attr/endX not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2911: error: resource android:attr/endY not found. /mnt/node_modules/@remobile/react-native-qrcode-local-image/android/build/intermediates/res/merged/release/values/values.xml:2919: error: resource android:attr/offset not found. error: failed linking references. * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/5.4.1/userguide/command_line_interface.html#sec:command_line_warnings BUILD FAILED in 4m 29s 120 actionable tasks: 97 executed, 23 up-to-date
Different but same for
./gradlew clean bundleRelease:
... Error: Unable to resolve module `../../release-notes` from `/mnt/screen/settings/releasenotes.js`: The module `../../release-notes` could not be found from `/mnt/screen/settings/releasenotes.js`. Indeed, none of these files exist: * `/mnt/release-notes(.native||.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)` * `/mnt/release-notes/index(.native||.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)` at ModuleResolver.resolveDependency (/mnt/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:163:15) at ResolutionRequest.resolveDependency (/mnt/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:52:18) at DependencyGraph.resolveDependency (/mnt/node_modules/metro/src/node-haste/DependencyGraph.js:283:16) at Object.resolve (/mnt/node_modules/metro/src/lib/transformHelpers.js:264:42) at dependencies.map.result (/mnt/node_modules/metro/src/DeltaBundler/traverseDependencies.js:399:31) at Array.map (<anonymous>) at resolveDependencies (/mnt/node_modules/metro/src/DeltaBundler/traverseDependencies.js:396:18) at /mnt/node_modules/metro/src/DeltaBundler/traverseDependencies.js:269:33 at Generator.next (<anonymous>) at asyncGeneratorStep (/mnt/node_modules/metro/src/DeltaBundler/traverseDependencies.js:87:24) > Task :app:bundleReleaseJsAndAssets FAILED > Task :app:bundleReleaseJsAndAssets_SentryUpload FAILED Processing react-native sourcemaps for Sentry upload. error:> Analyzing 2 sources No such file or directory (os error 2) Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output. Please attach the full debug log to all bug reports. FAILURE: Build completed with 2 failures. 1: Task failed with an exception. ----------- * What went wrong: Execution failed for task ':app:bundleReleaseJsAndAssets'. > Process 'command 'node'' finished with non-zero exit value 1 * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. ============================================================================== 2: Task failed with an exception. ----------- * What went wrong: Execution failed for task ':app:bundleReleaseJsAndAssets_SentryUpload'. > Process 'command 'node_modules/@sentry/cli/bin/sentry-cli'' finished with non-zero exit value 1 * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. ============================================================================== * Get more help at https://help.gradle.org Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0. Use '--warning-mode all' to show the individual deprecation warnings. See https://docs.gradle.org/5.4.1/userguide/command_line_interface.html#sec:command_line_warnings BUILD FAILED in 33s
So we did not find a tag and neither could we compile the app. Our verdict thus remains: not verifiable.
Not verifiable: The provided Open Source Code could not be verified to match the app released on Google Play
This verdict means that the provider did share some source code but that we could not verify that this source code matches the released app. This might be due to the source being released later than the app or due to the provided instructions on how to compile the app not being sufficient or due to the provider excluding parts from the public source code. In any case, the result is a discrepancy between the app we can create and the app we can find on GooglePlay and any discrepancy might leak your backup to the server on purpose or by accident.
As we cannot verify that the source provided is the source the app was compiled from, this category is only slightly better than closed source but for now we have hope projects come around and fix verifiability issues.
The app cannot be independently verified. If the provider puts your funds at risk on purpose or by accident, you will probably not know about the issue before people start losing money. If the provider is more criminally inclined he might have collected all the backups of all the wallets, ready to be emptied at the press of a button. The app might have a formidable track record but out of distress or change in management turns out to be evil from some point on, with nobody outside ever knowing before it is too late.