What I would love to see in a wallet
2024 Dec 03
See all posts
What I would love to see in a wallet
Special thanks to Liraz Siri, Yoav Weiss, and ImToken, Metamask
and OKX developers for feedback and review.
One critical layer of the Ethereum infrastructure stack, often
underappreciated by core L1 researchers and developers, is the wallet.
Wallets are the window between a user and the Ethereum world, and a user
only benefits from any decentralization, censorship resistance,
security, privacy, or other properties that Ethereum and its
applications offer to the extent that the wallet itself also has these
properties.
Recently, we have seen a lot of progress on improving user
experience, security and functionality of Ethereum wallets. The goal of
this post is to give my own views of some of the properties that an
ideal Ethereum wallet would have. This is not intended to be a complete
list; reflecting my cypherpunk leanings, it focuses on security and
privacy, and it is almost certainly incomplete on the user experience
front. However, I would argue that wishlists are less effective for
optimizing user experience than simply deploying and iterating based on
feedback, and so I think it is most valuable to focus on the security
and privacy properties.
User experience of
cross-L2 transactions
There is now an increasingly detailed roadmap for improving cross-L2
user experience, which has a short-term part and a long-term part. Here,
I will talk about the short-term part: ideas which are theoretically
implementable even today.
The core ideas are (i) built-in cross-L2 sends, and
(ii) chain-specific addresses and payment requests.
Your wallet should be able to give you an address that (following the
style of this draft
ERC) looks like this:
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@optimism.eth
When someone (or some application) gives you an address of this
format, you should be able to paste it into a wallet's "to" field, and
click "send". The wallet should automatically process that send in
whatever way it can:
- If you already have enough coins of the needed type on the
destination chain, send the coins directly
- If you have coins of the needed type on another chain (or
multiple other chains), use a protocol like ERC-7683
(effectively a cross-chain DEX) to send the coins
- If you have coins of a different type on the same or other chains,
use decentralized exchanges to convert them into the
right type of coin on the right chain and send them. This should require
explicit permission from the user: the user would see how much of what
they are paying, and how much the recipient is getting.
Mockup of possible wallet interface with cross-chain
address support
The above is for the "you copy-paste an address (or ENS, eg. vitalik.eth@optimism.eth) for
someone to pay you" use case. If a dapp is requesting a deposit (eg. see
this
Polymarket example) then the ideal flow is to extend the
web3 API and allow the dapp to make a chain-specific payment request.
Your wallet would then be able to satisfy that request in whatever way
it needs to. Making the user experience work well would also require
standardizing a getAvailableBalance request, and wallets would need to
put significant thought into which chains they store users' assets on by
default to maximize security and ease of transfers.
Chain-specific payment requests could also be put into QR codes,
which mobile wallets could scan. In an in-person (or online) consumer
payments scenario, the recipient would make a QR code or web3 API call
that says "I want X
units of token Y
on chain
Z
, with reference ID or callback W
", and the
wallet would be free to satisfy that request in whatever way it can.
Another option is a claim link protocol, where the
user's wallet generates a QR code or URL that contains an authorization
to claim a certain quantity of funds from their onchain contract, and
it's the recipient's job to figure out how to then move those funds to
their own wallet.
Another related topic is gas payments. If you receive assets on an L2
where you do not yet have ETH, and you need to send a transaction on
that L2, a wallet should be able to automatically use a protocol (eg. RIP-7755)
to pay the gas on a chain where you do have ETH. If the wallet
expects you to make more transactions on that L2 in the future, it
should also just use a DEX to send over eg. a few million gas worth of
ETH, so that future transactions can spend gas there directly (as this
is cheaper).
Account security
One way that I conceptualize the account security challenge is that a
good wallet should simultaneously be good in two areas: (i)
protecting the user from the wallet developer being hacked or malicious,
and (ii) protecting the user from their own mistakes.
The typo "mistakles" on the left was unintentional.
However, upon seeing it I realized that it's perfectly appropriate for
the context, so I decided to keep it.
My preferred solution to this, for over
ten years,
has been social recovery and multisig wallets, with graded access
control. A user's account has two layers of keys: a primary key,
and N guardians (eg. N = 5). The primary key is able to do
low-value and non-financial operations. A majority of the guardians is
required to do either (i) high-value operations, like sending away the
entire value in the account, or (ii) change the primary key or any of
the guardians. If desired, the primary key can be allowed to do
high-value operations with a timelock.
The above is a basic design, and can be augmented. Session keys, and
permissions mechanisms like ERC-7715,
can help support different balances between convenience and security for
different applications. More complicated guardian architectures, such as
having multiple timelock durations at different thresholds, can help
maximize the chance of successful legitimate account recovery while
minimizing the risk of theft.
Who or what should the
guardians be?
For an experienced crypto user who is inside a community of
experienced crypto users, a viable option is the keys of your
friends and family. If you ask each one to provide you with a
fresh address, then no one needs to know who they are - in fact, your
guardians don't even need to know who each other are. The chance that
they will collude without one of them tipping you off is tiny. For most
new users, however, this option is not available.
A second option is institutional guardians: firms
that specialize in performing the service of only signing a transaction
if they get some other confirmation that a request is coming from you:
eg. a confirmation code, or for high-value users a video call. People
have attempted to make these for a long time, eg. I
profiled CryptoCorp in 2013. However, so far such firms have not
been very successful.
A third option is multiple personal devices (eg.
phone, desktop, hardware wallet). This can work, but also is difficult
to set up and manage for inexperienced users. There is also the risk of
devices being lost or stolen at the same time, especially if they are at
the same location.
Recently, we have started to see more wallets based on
passkeys. Passkeys can be backed up on your devices
only, making them a type of personal-device solution, or backed up in
the cloud, making their security dependent on a complicated hybrid
of password security, institutional and trusted hardware assumptions.
Realistically, passkeys are a valuable security gain for ordinary users,
but they alone are not strong enough to protect a user's life
savings.
Fortunately, with ZK-SNARKs, we have a fourth option:
ZK-wrapped centralized ID. This genre includes zk-email, Anon Aadhaar, Myna
Wallet, and many others. Basically, you can take many forms of
(corporate or governmental) centralized ID, and turn it into an Ethereum
address, which you can only send transactions from by generating a
ZK-SNARK proving possession of the centralized ID.
What I would love to see in a wallet
2024 Dec 03 See all postsSpecial thanks to Liraz Siri, Yoav Weiss, and ImToken, Metamask and OKX developers for feedback and review.
One critical layer of the Ethereum infrastructure stack, often underappreciated by core L1 researchers and developers, is the wallet. Wallets are the window between a user and the Ethereum world, and a user only benefits from any decentralization, censorship resistance, security, privacy, or other properties that Ethereum and its applications offer to the extent that the wallet itself also has these properties.
Recently, we have seen a lot of progress on improving user experience, security and functionality of Ethereum wallets. The goal of this post is to give my own views of some of the properties that an ideal Ethereum wallet would have. This is not intended to be a complete list; reflecting my cypherpunk leanings, it focuses on security and privacy, and it is almost certainly incomplete on the user experience front. However, I would argue that wishlists are less effective for optimizing user experience than simply deploying and iterating based on feedback, and so I think it is most valuable to focus on the security and privacy properties.
User experience of cross-L2 transactions
There is now an increasingly detailed roadmap for improving cross-L2 user experience, which has a short-term part and a long-term part. Here, I will talk about the short-term part: ideas which are theoretically implementable even today.
The core ideas are (i) built-in cross-L2 sends, and (ii) chain-specific addresses and payment requests. Your wallet should be able to give you an address that (following the style of this draft ERC) looks like this:
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@optimism.eth
When someone (or some application) gives you an address of this format, you should be able to paste it into a wallet's "to" field, and click "send". The wallet should automatically process that send in whatever way it can:
Mockup of possible wallet interface with cross-chain address support
The above is for the "you copy-paste an address (or ENS, eg. vitalik.eth@optimism.eth) for someone to pay you" use case. If a dapp is requesting a deposit (eg. see this Polymarket example) then the ideal flow is to extend the web3 API and allow the dapp to make a chain-specific payment request. Your wallet would then be able to satisfy that request in whatever way it needs to. Making the user experience work well would also require standardizing a getAvailableBalance request, and wallets would need to put significant thought into which chains they store users' assets on by default to maximize security and ease of transfers.
Chain-specific payment requests could also be put into QR codes, which mobile wallets could scan. In an in-person (or online) consumer payments scenario, the recipient would make a QR code or web3 API call that says "I want
X
units of tokenY
on chainZ
, with reference ID or callbackW
", and the wallet would be free to satisfy that request in whatever way it can. Another option is a claim link protocol, where the user's wallet generates a QR code or URL that contains an authorization to claim a certain quantity of funds from their onchain contract, and it's the recipient's job to figure out how to then move those funds to their own wallet.Another related topic is gas payments. If you receive assets on an L2 where you do not yet have ETH, and you need to send a transaction on that L2, a wallet should be able to automatically use a protocol (eg. RIP-7755) to pay the gas on a chain where you do have ETH. If the wallet expects you to make more transactions on that L2 in the future, it should also just use a DEX to send over eg. a few million gas worth of ETH, so that future transactions can spend gas there directly (as this is cheaper).
Account security
One way that I conceptualize the account security challenge is that a good wallet should simultaneously be good in two areas: (i) protecting the user from the wallet developer being hacked or malicious, and (ii) protecting the user from their own mistakes.
The typo "mistakles" on the left was unintentional. However, upon seeing it I realized that it's perfectly appropriate for the context, so I decided to keep it.
My preferred solution to this, for over ten years, has been social recovery and multisig wallets, with graded access control. A user's account has two layers of keys: a primary key, and N guardians (eg. N = 5). The primary key is able to do low-value and non-financial operations. A majority of the guardians is required to do either (i) high-value operations, like sending away the entire value in the account, or (ii) change the primary key or any of the guardians. If desired, the primary key can be allowed to do high-value operations with a timelock.
The above is a basic design, and can be augmented. Session keys, and permissions mechanisms like ERC-7715, can help support different balances between convenience and security for different applications. More complicated guardian architectures, such as having multiple timelock durations at different thresholds, can help maximize the chance of successful legitimate account recovery while minimizing the risk of theft.
Who or what should the guardians be?
For an experienced crypto user who is inside a community of experienced crypto users, a viable option is the keys of your friends and family. If you ask each one to provide you with a fresh address, then no one needs to know who they are - in fact, your guardians don't even need to know who each other are. The chance that they will collude without one of them tipping you off is tiny. For most new users, however, this option is not available.
A second option is institutional guardians: firms that specialize in performing the service of only signing a transaction if they get some other confirmation that a request is coming from you: eg. a confirmation code, or for high-value users a video call. People have attempted to make these for a long time, eg. I profiled CryptoCorp in 2013. However, so far such firms have not been very successful.
A third option is multiple personal devices (eg. phone, desktop, hardware wallet). This can work, but also is difficult to set up and manage for inexperienced users. There is also the risk of devices being lost or stolen at the same time, especially if they are at the same location.
Recently, we have started to see more wallets based on passkeys. Passkeys can be backed up on your devices only, making them a type of personal-device solution, or backed up in the cloud, making their security dependent on a complicated hybrid of password security, institutional and trusted hardware assumptions. Realistically, passkeys are a valuable security gain for ordinary users, but they alone are not strong enough to protect a user's life savings.
Fortunately, with ZK-SNARKs, we have a fourth option: ZK-wrapped centralized ID. This genre includes zk-email, Anon Aadhaar, Myna Wallet, and many others. Basically, you can take many forms of (corporate or governmental) centralized ID, and turn it into an Ethereum address, which you can only send transactions from by generating a ZK-SNARK proving possession of the centralized ID.