Special thanks to Liraz Siri, Yoav Weiss, and the feedback and reviews from developers of ImToken, Metamask, and OKX.
A key layer in the Ethereum infrastructure stack is wallets, which are often underestimated by core L1 researchers and developers. Wallets are the window between users and the Ethereum world, and users can only benefit from any decentralized, censorship-resistant, secure, privacy-preserving, or other attributes provided by Ethereum and its applications, provided that the wallet itself possesses those attributes.
Recently, we have seen significant progress in Ethereum wallets in improving user experience, security, and functionality. The purpose of this article is to provide my perspective on some characteristics that an ideal Ethereum wallet should possess. This is not an exhaustive list; it reflects my crypto-punk tendencies, focusing on security and privacy, and it is almost certainly incomplete in terms of user experience. However, I believe that a wish list is less effective for optimizing user experience than simply deploying and iterating based on feedback, so I think focusing on security and privacy attributes is most valuable.
User experience across L2 transactions
There is now an increasingly detailed roadmap for improving the cross-L2 user experience, with both short-term and long-term parts. Here, I will discuss the short-term part: ideas that can theoretically still be implemented today.
The core idea is (i) built-in cross-L2 sending, and (ii) chain-specific addresses and payment requests. Your wallet should be able to provide you with an address (following the style of this ERC draft) as follows:
When someone (or some applications) provides you with addresses in this format, you should be able to paste it into the wallet's 'recipient' field and then click 'send'. The wallet should automatically handle sending the data in any possible way:
If you already have enough of the required type of tokens on the target chain, please send the tokens directly.
If you have the required type of tokens on another chain (or multiple other chains), use protocols like ERC-7683 (which is essentially a cross-chain DEX) to send the tokens.
If you have different types of tokens on the same chain or on other chains, use a decentralized exchange to convert them into the correct type of currency on the correct chain and send. This should require explicit permission from the user: the user will see how much they are being charged in fees, and how much the recipient will receive.
A possible wallet interface model with cross-chain address support
The above applies to the use case of 'you copy and paste the address (or ENS, e.g., vitalik.eth @ optimism.eth) for someone to pay you'. If a dapp requests a deposit (for example, see this Polymarket example), then the ideal flow is to extend the web3 API and allow the dapp to issue chain-specific payment requests. Then, your wallet will be able to satisfy that request in any needed way. To make the user experience good, it is also necessary to standardize the getAvailableBalance request, and the wallet must carefully consider which chains to default to storing user assets on to maximize security and transfer convenience.
Chain-specific payment requests can also be put into QR codes, and mobile wallets can scan the QR codes. In face-to-face (or online) consumer payment scenarios, the recipient will issue a QR code or web3 API call indicating 'I want X units of token YZ on-chain, with reference ID or callback W', and the wallet will be free to satisfy that request in any way. Another option is the claim link protocol, where the user's wallet generates a QR code or URL containing claim authorization to retrieve a certain amount of funds from their on-chain contract; the recipient's job is to figure out how to transfer those funds into their own wallet.
Another relevant topic is gas payment. If you receive assets on an L2 where you don't have ETH, and need to send transactions on that L2, the wallet should be able to automatically use protocols (like RIP-7755) to pay gas on the chain where you have ETH. If the wallet expects you to conduct more transactions in L2 in the future, it should also only use DEXs to send, for example, ETH worth millions in gas, so that future transactions can directly spend gas there (as it's cheaper that way).
Account Security
One way I conceptualize the challenges of account security is that a good wallet should play a role on both fronts: (i) protecting users from hacks or malicious attacks by wallet developers, and (ii) protecting users from their own mistakes.
The 'error' on the left is unintentional. However, when I saw it, I realized it fit perfectly in context, so I decided to keep it.
My preferred solution to this, for over a decade, has been social recovery and multi-signature wallets with tiered access control. Users' accounts have two layers of keys: a master key and N guardians (for example, N = 5). The master key is capable of performing low-value and non-financial operations. Most guardians need to perform (i) high-value operations, such as sending the entire value in the account, or (ii) changing the master key or any guardians. If needed, the master key can be allowed to perform high-value operations through time locks.
The above is the basic design, which can be expanded. Session keys and permissions mechanisms like ERC-7715 can help support different balances between convenience and security for different applications. More complex guardian architectures, for example, with multiple time-lock durations under different thresholds, can help maximize the chances of successfully recovering legitimate accounts while minimizing the risk of theft.
The above is the basic design, which can be expanded. Session keys and permissions mechanisms like ERC-7715 can help support different balances between convenience and security for different applications. More complex guardian architectures, for example, with multiple time-lock durations under different thresholds, can help maximize the chances of successfully recovering legitimate accounts while minimizing the risk of theft.
Who or what should the guardians be?
For experienced crypto users in the community, a viable option is the keys of your friends and family. If you ask everyone to provide you with a new address, then no one needs to know who they are - in fact, your guardians don't even need to know each other. If they don't tip you off, the likelihood of them colluding is low. However, this option is not available for most new users.
The second option is institutional guardians: companies that provide services that only sign transactions upon receiving other confirmation information at your request: for example, confirmation codes, or video calls for high-value users. These have long been attempted, for example, I introduced CryptoCorp in 2013. However, so far, these companies have not been very successful.
The third option is multiple personal devices (e.g., phone, desktop, hardware wallet). This can work, but it's also difficult to set up and manage for inexperienced users. There is also the risk of losing or having devices stolen simultaneously, especially if they are in the same location.
Recently, we have begun to see more solutions based on master keys. Keys can only be backed up on your device, making it a personal device solution, and can also be backed up in the cloud, making its security reliant on complex mixed password security, institutional, and trusted hardware assumptions. In fact, keys are a valuable security gain for the average user, but relying solely on them is not enough to protect users' life savings.
Fortunately, with ZK-SNARK, we have a fourth option: ZK-wrapped centralized ID. This type includes zk-email, Anon Aadhaar, Myna Wallet, etc. Essentially, you can take centralized IDs in various forms (corporate or governmental) and convert them into Ethereum addresses, where you can send transactions only by generating a proof of owning the centralized ID via ZK-SNARK.
With this addition, we now have a wide range of choices, and ZK-wrapped centralized IDs have a unique 'newbie-friendliness'.
To this end, it needs to achieve this through a simplified and integrated UI: you should be able to specify that you want 'example@gmail.com' as a guardian, and it should automatically generate the corresponding zk-email Ethereum address under the hood. Advanced users should be able to input their email (and possibly the privacy salt stored in that email) into open-source third-party applications and confirm that the generated address is correct. This should also apply to any other supported guardian types.
Note that a practical challenge zk-email faces today is that it relies on DKIM signatures, which use keys that rotate every few months, and these keys are not signed by any other authority themselves. This means that today's zk-email has a degree of trust requirement beyond the provider itself; this could be mitigated if zk-email used TLSNotary to verify updated keys in trusted hardware, but that is not ideal. I hope email providers begin to directly sign their DKIM keys. Today, I would recommend one guardian use zk-email, but not recommend most guardians use it: don't store funds in zk-email as being compromised means you cannot use the funds.
New users and in-app wallets
New users actually do not want to input a large number of guardians at the time of their first registration. Therefore, the wallet should offer them a very simple option. A natural approach would be to use zk-email on their email address, a key stored locally on the user's device (possibly a master key), and a backup key held by the provider, forming a 2-of-3 choice. As users gain experience or accumulate more assets, they should be prompted at some point to add more guardians.
Wallet integration into applications is inevitable because applications attempting to attract non-crypto users do not want to confuse the user experience with the need to download two new applications simultaneously (the application itself, plus the Ethereum wallet). However, many application wallet users should be able to link all their wallets together so that they only need to worry about one 'access control issue'. The simplest method is to adopt a tiered scheme, where there is a quick 'linking' process that allows users to set their primary wallet as a guardian for all in-app wallets. The Farcaster client Warpcast already supports this.
By default, the recovery of your Warpcast account is controlled by the Warpcast team. However, you can 'take over' your Farcaster account and change the recovery to your own address.
Protecting users from scams and other external threats
In addition to account security, today's wallets also do a lot of work to identify fraudulent addresses, phishing, scams, and other external threats, and strive to protect users from such threats. Meanwhile, many countermeasures are still quite primitive: for example, requiring clicks to send ETH or other tokens to any new address, regardless of whether you are sending $100 or $100,000. There is no single panacea here. This is a series of slow, ongoing fixes and improvements aimed at different categories of threats. However, continuing to improve here holds a lot of value.
Privacy
Now is the time to start taking Ethereum privacy more seriously. The ZK-SNARK technology is now highly advanced and privacy technologies that do not rely on backdoors to reduce regulatory risks (such as privacy pools) are becoming increasingly mature, while secondary infrastructures like Waku and ERC-4337 mempools are slowly becoming more stable. However, so far, conducting private transfers on Ethereum requires users to explicitly download and use 'privacy wallets', such as Railway (or for stealth addresses, Umbra). This adds great inconvenience and reduces the number of people willing to conduct private transfers. The solution is that private transfers need to be directly integrated into the wallet.
A simple implementation would be as follows. The wallet can store a portion of the user's assets as a 'private balance' in a privacy pool. When the user makes a transfer, they will automatically exit the privacy pool first. If the user needs to receive funds, the wallet can automatically generate a stealth address.
Additionally, wallets can automatically generate a new address for each application the user participates in (e.g., DeFi protocols). Deposits will come from the privacy pool, and withdrawals will go directly into the privacy pool. This allows the user’s activity in any one application to be unlinkable from their activity in other applications.
One advantage of this technology is that it is not only a natural way to transfer assets while protecting privacy but also a natural way to protect identity. Identity has already happened on-chain: any application that uses identity proof gating (such as Gitcoin Grants), any token-gated chat, Ethereum-following protocols, etc., are all on-chain identities. We hope this ecosystem can also protect privacy. This means that a user's on-chain activities should not be collected in one place: each project should store data separately, and the user's wallet should be the only thing that has a 'global view' of all their proofs simultaneously. An ecosystem where each user has multiple accounts natively helps achieve this, as do off-chain proof protocols like EAS and Zupass.
This represents a pragmatic vision for Ethereum privacy in the medium term. While some functionalities can be introduced on L1 and L2 to make privacy-preserving transfers more efficient and reliable, it is feasible to achieve this now. Some privacy advocates argue that the only acceptable thing is complete privacy for everything: encrypting the entire EVM. I think this might be the ideal long-term outcome, but it requires a more fundamental rethinking of the programming model, and we are not yet at a mature level ready to deploy on Ethereum. We do need default privacy to achieve a sufficiently large anonymous set. However, focusing first on (i) transfers between accounts and (ii) identity and identity-related use cases (such as private proofs) is a pragmatic first step that is easier to implement and that wallets can start using now.
Ethereum wallets also need to become data wallets.
One consequence of any valid privacy solution is that it creates a demand for users to store data off-chain, whether for payments, identity, or other use cases. This is evident in Tornado Cash, which requires users to keep 'tickets' representing deposits of 0.1-100 ETH. More modern privacy protocols sometimes store encrypted data on-chain and use a single private key to decrypt it. This is risky because if the key is leaked, or if quantum computers become feasible, the data could be completely exposed. Off-chain proofs like EAS and Zupass make the need for off-chain data storage more apparent.
Wallets not only need to become software that stores access rights on-chain but also need to become software that stores your private data. The non-encrypted world is increasingly recognizing this, for example. See Tim Berners-Lee's recent work on personal data storage. All the problems we need to solve around robust guarantees of access control, we also need to address around robust guarantees of data accessibility and non-leakage. Perhaps these solutions can stack together: if you have N guardians, use M-of-N secret sharing to store your data among those N guardians. Data is inherently more difficult to protect because you cannot revoke someone's data share, but we should propose as secure a decentralized hosting solution as possible.
Secure chain access
Nowadays, wallets trust their RPC providers to tell them any information about the chain. This is a vulnerability with two aspects:
RPC providers may attempt to steal money by providing them with false information, such as market prices.
RPC providers can extract private information about the applications and other accounts that users are interacting with.
Ideally, we want to close both of these gaps. To address the first issue, we need standardized light clients for L1 and L2 that can directly verify blockchain consensus. Helios has already done this on L1 and has been doing some preparatory work to support specific L2s. To correctly cover all L2s, we need a standard under which configuration contracts representing L2 can declare a function, possibly in a manner similar to ERC-3668, that contains the logic to fetch the latest state root and validate proofs against those state roots. This way, we can have a universal light client that allows wallets to securely verify any state or event on L1 and L2.
For privacy, the only realistic way today is to run your own full node. However, now that L2 is coming into view, running a full node for everything is becoming increasingly difficult. The equivalent of a light client here is Private Information Retrieval (PIR). PIR involves servers that hold all copies of the data and clients that send encrypted requests to the servers. The server performs calculations on the data and returns the data the client needs, encrypted to the client’s key, without revealing which piece of data the client accessed.
To keep the servers honest, individual database projects themselves are Merkle branches, so clients can use light clients to verify them.
The computational load of PIR (Private Information Retrieval) is very high. There are several ways to tackle this problem:
Brute force: improvements in algorithms or dedicated hardware may allow PIR to run fast enough. These technologies might depend on pre-processing: servers can store encrypted and shuffled data for each client, and clients can query that data. The main challenge in the Ethereum environment is to make these technologies adapt to rapidly changing datasets (just like nations). This makes real-time computation cheaper, but it likely makes total computing and storage costs higher.
Weaken privacy requirements: for example, there can only be 1 million 'mixins' per lookup, so the server will know the million possible values accessible to the client but will not know any finer granularity.
Multi-server PIR: If you use multiple servers and the honesty assumption between those servers is 1-of-N, then the PIR algorithm is generally faster.
Anonymity instead of confidentiality: requests can be sent through mixing networks, thereby hiding the sender of the request rather than hiding the content of the request. However, doing this effectively inevitably increases latency, thus worsening the user experience.
Finding the correct technological combination in the Ethereum environment to maximize privacy while maintaining practicality is an open research question, and I welcome cryptographers to attempt to do so.
Ideal key store wallet
In addition to transfer and state access, another important workflow that needs to work smoothly in the cross-L2 context is changing the account's validation configuration: whether it's changing its keys (for example, recovery) or making deeper changes to the logic of the account. Here are three layered solutions, ordered by increasing difficulty:
Replay updates: when users change their configuration, the message authorizing that change will be replayed on every chain where the wallet detects the user has assets. Possibly, the message format and verification rules can be independent of the chain, allowing for automatic replay on as many chains as possible.
Key store on L1: configuration information is located on L1, and wallets on L2 use L1SLOAD to read it or remote static calls. In this way, configuration only needs to be updated on L1, and it will automatically take effect.
Key store on L2: configuration information exists on L2, and wallets on L2 read it using ZK-SNARK. This is similar to (2), except key store updates may be cheaper, but on the other hand, reading is more expensive.
Solution (3) is particularly powerful because it aligns well with privacy. In typical 'privacy solutions', users have secret s, publish the 'leaf value' L on-chain, and prove L = hash(s, 1) and N = hash(s, 2) for some (never revealed) secret they control. An invalid symbol N is published, ensuring that future spending of the same leaf will fail without revealing L, which depends on the user's s security. A recovery-friendly privacy solution would say: s is a location (like an address and storage slot) on-chain, and users must prove the state query: L = hash(sload(s), 1).
Dapp Security
The weakest link in user security is often the dapp. Most of the time, users interact with applications by accessing websites, which implicitly download user interface code from servers in real-time and execute it in the browser. If the server is hacked, or DNS is hacked, users will receive a fraudulent copy of the interface that may trick them into performing arbitrary actions. Transaction simulation and other wallet features are very helpful in reducing risks, but they are still far from perfect.
Ideally, we would transfer the ecosystem to on-chain content version control: users would access dapps via their ENS names, which would contain the IPFS hash of the interface. Updating the interface would require on-chain transactions from a multisig or DAO. The wallet would show users whether they are interacting with a more secure on-chain interface or a less secure Web2 interface. The wallet could also show users whether they are interacting with a secure chain (such as stage 1+, multiple security audits).
For privacy-conscious users, wallets can also add paranoid mode, requiring the user to click to accept HTTP requests, rather than just web3 operations:
Possible interface model for paranoid mode
More advanced approaches go beyond HTML + Javascript and write the business logic of the dapp in a dedicated language (possibly a relatively thin layer on top of Solidity or Vyper). Then, the browser can automatically generate the UI for any required functionality. OKContract has been doing this.
Another direction is cryptoeconomic information defense: dapp developers, security companies, chain deployers, and others can establish a bond that pays affected users (as determined) by some on-chain adjudication DAO if the dapp is hacked or harms users in a highly misleading way. Wallets can show users a score based on the bond size.
Longer-term future
All of the above is done in the context of traditional interfaces, which involve pointing and clicking things and entering things into text fields. However, we are also at the brink of a more profound change in paradigm:
Artificial intelligence, which may lead us to shift from click-type typing paradigms to 'say what you want to do, and the robot will figure it out' paradigms.
Brain-computer interfaces, with both 'gentle' methods like eye tracking and more direct or even invasive technologies (see: the first Neuralink patient this year).
Client-side proactive defense: The Brave browser actively protects users from ads, trackers, and many other undesirable objects. Many browsers, plugins, and crypto wallets have teams actively working to protect users from various security and privacy threats. These 'active guardians' will only become stronger in the coming decade.
These three trends together will lead to a deeper rethinking of how interfaces work. With natural language inputs, eye tracking, or ultimately more direct brain-computer interfaces, combined with your history (perhaps including text messages, as long as all data is processed locally), the 'wallet' can clearly and intuitively understand what you want to do. Then, artificial intelligence can translate this intuition into a concrete 'action plan': a series of on-chain and off-chain interactions to achieve what you want. This can significantly reduce the need for third-party user interfaces. If users do interact with third-party applications (or other users), AI should represent the user in adversarial thinking, identifying any threats and suggesting an action plan to avoid threats. Ideally, these AIs should have an open ecosystem, produced by different groups with varying biases and incentive structures.
These more radical ideas depend on technology that is very immature today, so I wouldn’t put my assets into wallets that rely on them right now. However, similar things seem clearly to be future trends, so it's worth starting to explore more actively in that direction.