There was a logic error that caused the load screen to cover the create/restore screen because the load screen was waiting for the synchronizer to start but it would not start until after the wallet was created (or restored). The simple fix was to turn off the load screen during the create/restore flow and then reactivate it, if needed while creating the syncrhonizer. In almost all cases, users will not see the load screen. However, when there is a race condition and the homescreen attempts to draw before the synchronizer is ready, it will now display a load screen instead.
Existing users of seed-only wallets were getting stuck because the birthday is now stored differently. The previous fix was attempting to just load the latest checkpoint as the birthday but this does not work because the birthday determines how far back the wallet will rewind during a reorg. The end result prevented the wallet from going back as far as it needed. When the birthday isn't known, it makes logical sense to set it to the lowest possible number: Sapling Activation. This also happens to fix the problem because now wallets that are upgrading can rewind beyond the latest checkpoint.
This helps with managing the race condition at startup where existing wallets want to show data quickly but need to wait for the synchronizer to be fully ready, which often happens slower than how long it takes the screen to draw itself.
We now take metrics on how long devices are taking to create transactions so we can begin to understand which devices are in having a bad user experience and later know precisely how much our performance improvements have helped. We also now track submission response errors to help us pinpoint when and why transactions are failing. This is very useful as the canopy grace period expires and transactions begin to not appear for some testers.
Previously, wallets would crash before launching because only the seed was stored. Now, the wallet works with only viewkeys so these older wallets need to store that value at least once. This does that and also adds troubleshooting code to try and find any similar edge cases and report on whether this work around corrected the issue. For internal use only, of course.
Previously, certain phones could press cancel to bypass biometrics. Others couldn't even enter the send flow. Google's library for this is still not stable but it has improved and the underlying issue that contributed to these bugs has been corrected.
The SendFinal screen would completely break after pressing cancel. Pressing back would return to other screens but not actually clear the SendFinal fragment out. This workaround fixes that but there is still weird behavior when users press back. This is good enough for this release.
This allows the app to run alongside the play store version for internal testing within the wallet team. This proved to be super useful so we formalized it into its own build with a separate icon and app name.
ViewingKeys would sometimes get written in one way but not read back the same, dependeing on length. This was hard to catch because it only happened about 30 percent of the time. The fix was to update the secure storage library to work with lists and maintain order. A PR was submitted upstream but we are also going to seek out a better library to use going forward.
Pulled out all strings and also cleaned up warnings along the way. Introduced base translation files, one of which is mapped directly to the excel spreadsheet of translations.
- Changed style of input boxes
- Updated button behavior to only enable when values have changed
- Added simple loading screen
- Added error handling messages when the change server fails
- Switched button order and simplified button text
- Added red validation messages below input
- Respond to user input, as they type
- Reformatted title area to match other screens
- Adjusted layouts to be percentage based to work more consistently on smaller screens
- Implemented logic for restoring the original server values
Removed the buttons that allowed navigation between the two screens, which has the nice benefit of removing the second way that the user could enter the Send flow. Lastly, split the address back into 8 parts and did other UI cleanup on the receive screen.
Most of these changes center around managing addresses. We might want to further compose the MainActivity and allow another object to handle these capabilities but for now they live in a place that's central for all fragments.
Since we do not want to pester users most of our dialogs, going forward, will prompt the user select a setting not to see them again. This commit also gets rid of two separate approaches for sharedPreferences and settles on a second instance of lockbox. Our current lockbox is used for keys so we create another that contains no cryptographic info and use it for settings. This will use the device's secure element, when present and do the most secure thing falling back to our minSDK.
which automatically handles some of the more complex state management. Without this change, the recyclerview would lose its scroll position after viewing tx details. Now it handles it perfectly due to setting transactionAdapter.stateRestorationPolicy =
RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
If a crash occurs before feedback is started then attempting to report that crash will, itself, crash because the lateinit feedback instance is not initialized. The result is a black screen on launch! This fixes that by catching everything while trying to report an error.