/quarkton-contest

QuarkTON Wallet. A special repository only for contest snapshot of code. For actual further development see https://github.com/Skydev0h/quarkton

Primary LanguageKotlinMIT LicenseMIT

QuarkTON

This is an entry for TON Wallet Challenge contest.

Much work was done to make sure that all flows are accounted for, user experience is smooth and further improvements of the application would be easy.

Building

To build you need to:

  • Download and install Android Studio Hedgehog | 2023.1.1 Canary 5
  • Install SDK Platform 33 (application is targeted to it), latest versions of SDK Build-Tools, Command-Line tools
  • Open the project in Android Studio
  • Select app in Project tree and click Make Module (hammer with blue square) or do Make Project (green hammer)
  • Downloading of dependencies, build plugins, synchronizing, etc. may take considerable time
  • After build is complete result will be in app/build/outputs/apk/debug/app-debug.apk file

Some notes

Important note about build process: Sometimes compilation may fail due to some strange error (IR lowering failed, Internal compiler error or unable to remove some file). That error is temporary and is not caused by the project or the code. To fix it just run the compilation again and everything should work smoothly.

About the Android Studio version: it might work in stable version because first I was developing in it, but later switched to Canary ones but did not upgrade Gradle or plugins, therefore it should still work on stable version, but that needs to be checked. Just for peace of mind it is better to use the Canary version.

Features

The application is striving to meet all the contest requirements with the addition of some more very useful features.

Notable features of the application are:

  • Very wide compability. The contest requires at least 3 major versions compability, the application supports up to Android 6 (that's 7 versions!). Actually I have tested it on my ancient Galaxy Note 10.1 running Android 6.0.1 version and it worked great!
  • No native libraries are used at all! That includes lite server connections, displaying of lottie files or QR code scanning. This makes application pretty lightweight (especially on release mode when all unneeded library code is removed) and very compatible with all architectures.
  • There are no dependencies on Google Play Services or some Firebase stuff. Therefore all application features work on any Android phone either with Play Services installed or not. This is especially crucial for phones like new Huawei models that cannot
  • All layouts and animations were carefully crafted, checked, reviewed, adjusted, and evaluated. A huge effort was done to make sure that the following points are satisfied simultaneously:
    • Everything matches provided mockups as close as possible.
    • User experience is smooth and intuitive, I looked not only from developer but from user's point of view.
    • Animations match actions, location of elements and are implemented as smooth as possible.
  • Preferences that contain seed phrase are encrypted by a key securely stored by Android for the application. Also, backup policies and configurations are set up the way that backing up app and extracting seed phrase from it is plain impossible (without root, of course, and even without root you would need to find a way to get your hand on the key).
  • Wallet balances, transactions and used DNS names (for reverse lookups) are cached in local database of the application. They are kinda stateless because they are obtained from the blockchain, and even wiping that database (without preferences) would not be a destructive action.
  • The requirement of scrolling down main wallet screen and then transactions list uninterrupted was actually implemented. This is a separate feature because generally two containers that scroll to same direction one inside another are considered to be impossible to implement adequately with any normal user experience. I was able to attain that by doing some VERY interesting hacks with intercepting, consuming and scolling stuff on that page. Make sure to check that code out!
  • In the backend, many lite servers are queried in random order to obtain data in race fashion. Therefore, it is enough to receive one answer from many to get result. This important feature allows to make app work much faster and overcome issues with broken or unreachable (censored) lite servers. On the other hand in some situations data can be collected from many servers (like obtaining transactions that are not on all lite servers or resolving TON DNS) and processed from all of them to trade speed for functionality and integrity when required.
  • Seed phrase is generated securely! The problem with this is that ton-kotlin uses secure random generator to seed weak prng with just 64 bits of entropy. That would cause all seeds generated by ton-kotlin to have just 64 bits of entropy instead of 240 in normal seed. This is fixed by a custom running-and-changing seed phrase generator that uses purely secure random generator and is provably not worse in entropy terms with regenerating seed phrase each round.
  • Support of 12, 18 and 24 words TON seed phrases. This could be most useful with future feature of supporting standard seed phrases in addition to TON ones.
  • Support of private key import. You can directly use your private key (in hex format or .pk file) to access your wallets. This very powerfully synergizes with two following features.
  • Ability to use any wallet version, from v1R1 to v4R2. This allows to access coins in any existing wallet version and transfer them to the newest v4R2 if desired.
  • Masterchain wallets can be used and are explicitly marked as such in the list behind a special toggle. This combining with two previous features allows people who still have their private keys from long time ago to easily access any their wallet, any version and use their coins
  • Additional safeguards were added to decrease frustration of users. For example, during onboarding process, if going back would cause removal of ephemeral generated or imported seed phrase in memory (because for security it is commited only after setting up passcode) a warning dialog is displayed explaing this and asking user if that is really what they want.
  • When entering seed phrase the input boxes have very convenient UX: when you finish typing a word focus automatically switches to next box - this way you can type seed phrase pretty fast without interruptions of switching boxes or selecting words from hints.
  • QR Code scanner correctly scans both normal and inverted codes with reasonably high resolution that makes it easier to use high-density inverted codes such as TON Connect ones. Also the scanner also identifies plain address without schema - such as used by wallet bot in Telegram.
  • Transaction details are improved - by clicking corresponding row you can extend it and view the full address or transaction id. Long-clicking them will copy it to the clipboard. Same functionality is implemented for sending final screen where comment can be entered.
  • Currency selection window conveniently displays value of your currently selected wallet in all supported currencies at a glance. From there currency can be easily changed with just one tap.
  • Wallet selection screen displays balances of all wallet versions which allows you to really easily see if there are any remaining TONs on your old wallets. To tradeoff the required traffic and waiting time refresh is manual (except first login) and last refresh time is conveniently displayed at top of that window in real-time.
  • You can enable or disable advanced security level - whether it is required to use passcode or fingerprint each time transaction is sent or just passing lock screen is sufficient. This allows to adjust security / convenience tradeoff as the user likes.
  • Deletion of wallet has a separate screen explaining consequences of that action and is protected by a passcode (without option for fingerprint for advanced security).
  • Receive QR code is generated as a vector and actually can be easily increased in size by tapping it. Such feature will make it easier to share your wallet address.
  • Comments are parsed in every possible adequate manner - they can begin with normal 32-bit opcode, 8-bit opcode, or even do not have one if they entirely fit ASCII range.
  • A sticky date header is displayed in transaction list so that if you have lots transactions on a specific date you would not get lost in them.
  • A reasonable amount of transactions is loaded first, then you can load more by pressing a button. Also you can press another button to go to explorer and take a look at your account there. This is especially useful when your transactions are very old and servers have no information about them.
  • A very specific use case is handled if account has previous transactions but lite servers do not know about them with letting user know about the condition and giving them ability to take a look at their transaction history in explorer with one tap.
  • Balances and transactions in the wallet are periodically automatically refreshed when wallet is active at least once a minute to make sure the data is latest.
  • When sending TON on the amount screen balance is also periodically refreshed and can be manually refreshed by tapping on it. This provides ability to send TONs that might have been received during entering address or amount to send without leaving it and having to re-enter everything again.
  • Transaction comment edit box very accurately and precisely counts amount of bytes in the comment therefore you can mix in latin, cyrrilic, and even hieroglyphs - unlike clients that might just divide length by 2 if they see any cyryllic character or do not take that into account and cause overflow here you can fit as much as possible without errors.
  • Unlike the mockups, you can scan QR codes from gallery even if camera access is not provided - it is not actually needed to get a photo from gallery and scan QR code from it.
  • TON Connect is very maintainable. The idea that even was actually implemented and is kinda working, if App did not disconnect immediately upon connection, is that only one DApp can be active at a moment, and it is prominently displayed on main wallet screen. This increases security of user because if multiple apps were active at the same time it would be impossible (from provided implemented mockups) to understand which of DApps requested that transaction. Therefore there can be only one foreground and active DApp connection that can be easily disconnected, connected or be hidden from main wallet screen and all the connections can be maintained from a specialized TON Connect Settings screen that could be invoked by pressing a special button in action bar.

Planned features

Planned features that I really wanted to implement but, well, TON Connect took too much time and I did not manage to implement them in time.

Some of the plans are even huge features that were not at all intended to be implemented during the contest, but I hope that I will continue developing this project.

  • Support of Standard seed phrases in addition to TON ones. This feature would allow to use this wallet to manage, for example, TON coins in Trust Wallet or recovering access to Ledger-backed coins. The issue here is correctly deriving the keys for the wallets from those, I have not managed to find a way to match the address in Trust Wallet.
  • Ability to use hardware tokens, first and foremost, Ledger Nano X and Ledger Nano S (and +). This is quite a considerable amount of work but no wallet have yet integrated this feature into a full fledged wallet application. Actually, this was planned to really be included and I am still planning to do it later to have an adequate wallet to manage my TONs on my Ledger.
  • As an software addition to the previous point I have planned and still hope to in future to implement support for ANY compatible Ledger application, that includes TON v1, TON v2 and possibly Everscale applications (because only TON v1 and Everscale (based on v2) are in official Ledger store and can be installed to Ledger Nano X, and TON v2 cannot, and has to be sideloaded to Ledger Nano S (or +)).
  • Jettons and NFTs support. It is not as straightforward and easy as it would be with using simple HTTP APIs. Indexing Jettons and NFTs requires walking through ALL transactions of a wallet, decoding them, creating a local index of relevant jetton and NFT wallets, and also need to implement manipulation layer for them.
  • Proper reverse-lookup of DNS names. I theoretically consider this next to impossible because to do that you need to download ALL database of ALL domains in TON, and while now it should be quite small, over time, it has linearly unbounded size. Therefore it is very inefficient without some kind of dedicated server. Moreover, no trust to that server is required because you can recheck the reverse by performing forward lookup.
  • Ability to choose your favorite explorer aside TON Scan one. Here need to adjust code flow to give more information to link creation routine, since each explorer has their own format - some include LT, some dont, some use HEX, some use B64, no standartization in that at all.
  • Multiple accounts support. This should be not too hard to implement, but I did not want to introduce new bugs while short on time.
  • Add HighLoad wallet support. This was deferred as low priority task due to HUGE difference how it needs to be interacted with.
  • Properly verify proofs for smart contract invocations. As of now that only affects DNS but very slightly, since a security model built to mitigate and compensate it is to query random 11 lite servers for DNS resolution and make a majority vote. Therefore, upto half a servers can provide incorrect answers, while majority answers correctly this guarantees integrity of obtained data.
  • Do a grand refactoring of all this code since it was written in a hurry in 2 weeks and for further development could be rewritten in a much better manner. Moreover this was my first Kotlin Android application project ever, therefore I have catched new patterns and knowledge on the fly and now understand that everything could be done even better.
  • Add support to more customization of how wallets are selected. For example, add ability to choose Wallet ID for v3+ wallets because some people might use Wallet ID 0 or 1 or something like that when interacting with them in command line while the default constant was not yet defined.
  • Finish implementation of TON Connect 2.0. The only thing remains for now is management of bridges - that UI.
  • Add integrated browser for connection using JS bridge to the applications. This would make it possible to not depend on an external bridge server.
  • Actually add FCM and a special service that would monitor all new transactions in the network and send out notifications to clients when their wallet state is changed. This does not compromise security in any way since actual data would be pulled from blockchain through lite servers and only notification to do that is received.
  • Consider using native tonlib to ensure the highest level of security, however, at the cost of huge performance and storage (both app size and on the disk) implications
  • Add ability to send up to 4 messages in one transaction - that just requires to implement a sophisticated UI for such ability.
  • Correctly and precisely estimate instead of approximation. Without using external API that requires running entire TVM inside the phone and that most likely would require adding the behemoth tonlib to the party.