Confusion when the wallet is awakened
Connecting a wallet is a key step into the Web3 world. Web3 users often need to connect their wallets on some DApp websites. However, just this simple action may also cause serious inconvenience to users.
Connecting a wallet
Imagine a scenario like this: a new Web3 user (out of curiosity, he installed many plug-in wallets), visited a DApp website, and wanted to use his browser plug-in wallet to connect to it, but when they clicked the "Connect Wallet" button provided by the website and selected a wallet to use it to connect to the DApp, they might find that the wallet that popped up was not the one they chose. This is likely to make him panic and suffocate, thinking that his computer was infected with a virus, so he performed an unexpected operation.
Blockchain wallets are an important entrance to connect to the blockchain, and in order to occupy this entrance, each wallet uses every way they can think of. The most annoying thing for DApp developers and DApp users is the tampering of global variables by various wallets.
In the current browser wallet implementation logic, global variables are injected into the browser to expose the functions provided by the wallet (for example, the wallet of the Ethereum platform will inject its functions into "window.ethereum"), so that DApp can call the methods provided by the wallet to interact with it.
However, since many wallets will inject themselves into the same window.ethereum variable, the wallet registered later will overwrite the wallet registered earlier, so that only the last registered one can be called up in this way.
Sometimes, in order to use the wallet they want to use normally, DApp users have to temporarily disable other wallet plug-ins, or directly install only one wallet. This is very different from the original idea of the wallet developer. And even if the new wallet is better, it is difficult to attract users who are already using other wallets.
Some friends may wonder why it is necessary to inject into the same variable? Suppose there are two wallets: A and B. In fact, as long as A injects itself into "window.a" and B injects itself into "window.b", the method provided in the corresponding object will be called to wake up the wallet, and the above problem of calling B instead of calling A will not occur. This can indeed solve the competition problem, but the problem is that if the DApp is to support multiple wallet connections, all the wallet names that the developer wants to adapt must be pre-defined in the code, and when the user selects a wallet, the relevant methods of the wallet are called. This makes the maintenance of the relevant code quite troublesome. Injecting the wallets into the same object uniformly can avoid this trouble.
Solution
In order to get rid of the above dilemma, there are two similar standards in the community.
Ethereum's solution: EIP-6963
The Ethereum community proposed the EIP-6963 proposal in May 2023.
The basic logic is very simple, which is to abandon global variables and use agreed events to solve the problem of wallet registration and discovery.
Specifically, after the plug-in wallet is loaded successfully, a unified "eip6963:announceProvider" event is triggered to notify DApp that a new wallet is available. DApp listens to this event to find out which wallets are currently available.
In this way, through a set of abstract event monitoring logic, the problems caused by the direct use of global variables are avoided, and the wallets available in the current user environment can be automatically discovered. In this way, the dilemma is solved.
Community Standard: Wallet Standard
EIP-6963 is the Ethereum ecosystem standard, but not only Ethereum, other chain platforms will also have similar problems. For example, the wallets of the Solana chain generally inject themselves into the "window.solana" variable, which will also cause competition.
So can the Solana ecosystem also implement this standard? Although EIP-6963 is only to solve the wallet discovery problem in the Ethereum ecosystem, the ideas contained in it can actually be applied to all chain platforms. So, can we go a step further and provide a set of universal standards for wallets and DApps on all blockchain platforms to implement, so that developers and users of all chain platforms can enjoy the convenience provided by EIP-6963? In theory, there is no problem at all, and some developers are already doing this, that is, Wallet Standard.
The core work of Wallet Standard is to provide two functions: "registerWallet" and "getWallets", the former is used for wallets, and the latter is used for DApps.
The wallet calls "registerWallet" and passes in a wallet object, which encapsulates the functions provided by the wallet (such as the Connect method, which is used to connect to the wallet). A RegisterWalletEvent event will be triggered inside the function. The parameter of the event is actually a callback function, which is used to let DApp listen to the RegisterWalletEvent event and call it. This callback function actually passes in the wallet object, so DApp can get the wallet object reference and interact with the wallet.
DApp developers do not need to write their own code to listen to and receive wallet objects. This part has been built into "getWallets" by Wallet Standard. However, getWallets only listens to events, and developers still need to consider how to handle events. For example, where should the obtained Wallets be placed? Some wallets are loaded before the DApp is loaded, while others may be loaded later. How to maintain the status of these wallets? In response to the above details, Wallet Standard also provides the "@wallet-standard/react" package. Developers can directly use the React Hooks it provides to obtain the desired data, including wallet lists, currently connected wallets, methods provided by wallets, etc.
Wallet Standard Features
In addition to the most basic acquisition of Wallet objects, Wallet Standard also defines some Features formats.
In fact, wallets have some basic functions, such as connection, monitoring wallet events, etc. Wallet Standard provides features such as "standard:connect" and "standard:events". After the wallet vendor implements these features, DApp can directly determine whether the wallet supports certain operations based on these values.
The "standard:*" mentioned above is its built-in defined features. In fact, there are no particularly strict requirements for their values, so they can be extended at will. Different chain platforms will also have their own unique features. For example, Solana can directly agree on "solana:*". Common features of the Solana platform include "solana:signTransaction", "solana:signMessage", etc.
Current Status of Wallet Standard
Currently, there are not many projects that have implemented the Wallet Standard standard. Solana and Sui are worth mentioning.
In the Solana adapter of Ant Design Web3, automatic detection of wallets adapted to Wallet Standard is also supported. Developers basically only need to turn it on through an "autoAddRegisteredWallets". There is no need to configure a lot of wallet metadata, and the development experience and user experience are rising sharply.
ZAN.TOP's logic for connecting to wallets also encountered the same problem in the early days, but now, thanks to the configuration provided by Ant Design Web3, it is easy to adapt to the EIP-6963 standard. Everyone should have experienced this when binding an address at https://zan.top/personal/account?chInfo=ch_wxdyh.
Implementation of each blockchain ecosystem
Currently, various blockchain platforms have different attitudes towards the Wallet Standard (or EIP-6963) standard. Here are a few examples:
Bitcoin
Bitcoin does not seem to have a similar standard so far. There is a project that implements the Wallet Standard standard, but it has not attracted much attention and has not submitted new code for a long time.
Currently, developers can only maintain the state manually or use some development kits to assist the work. For example, in the Bitcoin adapter implementation in Ant Design Web3, for different wallets, different global variables will be obtained and stored in a unified state. This is actually equivalent to the library developer taking over the tedious state maintenance work. Moreover, this only solves the problem of wallet conflicts, and the problem of not being able to automatically sense available wallets still exists.
Ethereum
The Ethereum platform already has the EIP-6963 standard, and most related libraries and wallets also provide support.
Solana
As mentioned above, the official implementation is provided: https://github.com/solana-labs/wallet-standard
Sui
Sui has currently provided an implementation for Wallet Standard. The usage method can be found in the official document: https://docs.sui.io/standards/wallet-standard
Support for DApps development libraries
wagmi
wagmi provides support for EIP-6963 through the mipd (https://github.com/wevm/mipd) library. For specific methods, please refer to wagmi's documentation.
RainbowKit
RainbowKit (https://www.rainbowkit.com/) has built-in support for EIP-6963, as its internal logic is based on wagmi.
Ant Design Web3
Ant Design Web3's (https://web3.ant.design/) Ethereum and Solana adapters support both standards very well, and are very portable for developers to enable.
For Ethereum DApp developers, you only need to add the eip6963 configuration. Note that the ones related to EIP-6963 are in lines 23-25:
If you are a DApp developer in the Solana ecosystem, the method is similar. It provides the autoAddRegisteredWallets property:
Summary
EIP-6963 and Wallet Standard can greatly improve the user experience of connecting to wallets and lower the entry threshold for new wallet providers. I hope that more chain platforms, wallets, and DApp developers can provide or implement relevant standards in the future, which will help Web3 develop in a better direction.