Metamask-extension: Allow dapp to disconnect accounts

Created on 15 Jul 2020  路  12Comments  路  Source: MetaMask/metamask-extension

What problem are you trying to solve?

With the new updates to v8, it is important for the dapp developer to be able to disconnect an account. Otherwise, there is no way to handle account mismatch scenarios. Also without it, the user must manually disconnect their account in the MetaMask settings, which is a poor user experience.

Describe the solution you'd like

An Ethereum Provider API like ethereum.disconnect() or ethereum.close()

Additional context

Related to #8956 . This would fall under the proposed Hard mode developer experience. This functionality is vital to being able to provide a streamlined experience for our dapp.

WalletConnect and WalletLink both implement this functionality.

All 12 comments

There are probably other ways of handling the account mismatch scenarios that you're describing. Could you give us a concrete example that we could use to work on?

Ok. The account mismatch scenario is not actually my issue, it was just an example.

My actual issue is the second example. I have a "disconnect" button, which will log a user out, so they can log in again with a different wallet. My dapp is designed for using 1 wallet at a time, in order to simplify things.

Megan has logged in using MetaMask account1. She now wants to use MetaMask account2. She clicks the Disconnect button, and returns to the login page. When she selects MetaMask, the dapp calls .enable() however she is not prompted to select a different account. She has no other option than to go into her MetaMask settings and manually disconnect the dapp.

If I could call disconnect with the Ethereum provider API, this would allow Megan to go through the initial .enable() flow again, without needing to use the MetaMask settings.

This is similar to Roman鈥檚 request, wanting a way to re-prompt the user for possibly different accounts. I believe you can get this result today by either using the wallet_requestAccounts method or wallet_requestPermissions for the eth_accounts permission. I will verify this in the morning, need to do dinner now.

One thing you could do also is to just use disconnect to represent local app state, and if a user disconnects again and then connects again and selects MetaMask, use the existing permission to resume the user鈥檚 session with no prompt. If the user switches account, they will be prompted within MetaMask to connect if they want, and your app can refer to accounts[0] as their most recently selected account.

When she selects MetaMask, the dapp calls .enable() however she is not prompted to select a different account. She has no other option than to go into her MetaMask settings and manually disconnect the dapp.

She does have another option; switching accounts within MetaMask. The MetaMask UI has always been the sole method of switching between accounts. If a user wants to switch accounts on a dapp, they use the MetaMask account menu. If a dapp wants the user to switch accounts, they ask the user to switch accounts within MetaMask (using the account menu). This was true before v8 as well.

Does that handle your scenario adequately? Or is there some other scenario that warrants this disconnect feature?

a way to re-prompt the user for possibly different accounts.

This would be great. Thanks I'll try out your wallet_requestAccounts suggestion and see if that will suffice.

Thanks @Gudahtt . I would really like the behavior to work the same for all wallet types (WalletConnect, WalletLink). So disconnect should actually feel like a disconnect, and it should do what the user expects.

I don't think that just keeping it the way it has always been is a good argument. I know MetaMask is working hard to update UX after feedback, but I also think I should have the power to use it however I want to provide the best experience for my users. If I can provide a better experience in my dapp for the user, then I should be able to. Asking the user to interact with their metamask settings for something so simple is a bit of a backwards step.

I didn't mean to suggest that allowing dapps to disconnect was a bad idea necessarily. I would just like to understand the motivation. I doubt we're likely to design any such method well without understanding the use cases well.

I'm still having trouble understanding why a dapp would want to encourage a user to disconnect. The initial connection signifies that the user trusts the dapp enough to see their account(s), so I can see the user wanting to disconnect if they lost trust somehow. Or maybe the user doesn't intended to use the dapp anymore, and wants to disconnect to de-clutter their wallet permissions. But neither of those are of concern to a dapp.

I'm not encouraging disconnection. I'm just trying to provide the simplest, easiest interface for managing multiple accounts. Logging in/out of the app is the most familiar "web2" method to achieve this. I like the KISS way of doing things.

I could add a switching account feature like Google does, but I think that's overkill, and would unnecessarily complicate an otherwise straightforward app. It would require much more design and development cycles as well

This would be great. Thanks I'll try out your wallet_requestAccounts suggestion and see if that will suffice.

On a second look, it turns out the method you want is wallet_requestPermissions to re-prompt regardless of previously granted permissions.

So:

const permissions = await ethereum.request({
  method: 'wallet_requestPermissions',
  params: [{
    eth_accounts: {},
  }]
});

Trying now. will report back and close this issue if I am successful :)

I tried both eth_requestAccounts and wallet_requestPermissions

Neither will trigger the prompt again.

UPDATE: Scratch that. wallet_requestPermissions is working now

Great success! Pasting code here for others.

    const walletAddress = await window.ethereum.request({
      method: "eth_requestAccounts",
      params: [
        {
          eth_accounts: {}
        }
      ]
    });

    if (!isReturningUser) {
    // Runs only they are brand new, or have hit the disconnect button
      await window.ethereum.request({
        method: "wallet_requestPermissions",
        params: [
          {
            eth_accounts: {}
          }
        ]
      });
    }

metamask flow

Was this page helpful?
0 / 5 - 0 ratings