Deprecating “Synchronous” Provider Methods

Erik Marks
MetaMask
Published in
3 min readOct 31, 2019

This article is outdated. Please see this article and this GitHub issue for details on upcoming changes.

As part of the exciting changes we are making to the MetaMask platform, an upcoming update to our inpage provider RPC API may be breaking for a small number of dapp developers. If you are a dapp developer, we encourage you to keep reading.

Summary

We are deprecating the synchronous behavior of RPC methods called using ethereum.send(requestObject) of the MetaMask inpage provider in early 2020. The affected methods will still be callable in the same way, but their results will be resolved from a Promise rather than returned directly. Furthermore, the RPC method results will be resolved directly, rather than wrapped in a JSON RPC response object. The affected methods are:

  • eth_accounts
  • eth_coinbase
  • eth_uninstallFilter
  • net_version

As part of this change, all RPC methods supported by MetaMask will be callable using ethereum.send(methodName, params) or ethereum.send(requestObject). Please see here for our release schedule.

Who is affected?

If there are any calls of the form ethereum.send(requestObject) in your dapp that expect anything other than a Promise, you are likely to see exceptions or undefined behavior in subsequent logic. Moreover, per EIP 1193, these Promises resolve directly to the method call’s result, which will not be wrapped in a JSON RPC response object.

So, for example:

// instead of this:accounts = ethereum.send({ method: 'eth_accounts' }).result// you will have to do this:accounts = await ethereum.send('eth_accounts')// or this:accounts = await ethereum.send({ method: 'eth_accounts })// or if you're not using async/await:ethereum.send('eth_accounts').then((accounts) => {
/* Deal with them */
})

Why are we doing this?

While the aforementioned methods currently behave synchronously, the data they return is anything but. Behind the scenes, the data is kept up-to-date through asynchronous messaging between the inpage provider and the MetaMask background script. Indeed, with the changes we’re introducing, the value returned by a “synchronous” ethereum.send({ method: ‘eth_accounts’}) would be the latest value returned by either an accountsChanged event handler or an asynchronous RPC request for the same method!

In addition, per EIP 1193, Ethereum providers should return Promises that resolve to the RPC method’s result, rather than an RPC response object. All our added functionality will work in this way, and these methods must be brought up to par.

What should you do instead?

The next version of the MetaMask inpage provider will be fully compliant with both EIP 1102 and EIP 1193. The latter specifies a number of events — particularly accountsChanged, networkChanged, and chainChanged — that you should listen for using ethereum.on(eventName, callback). This is the best way to ensure that your view of the user’s selected address and network is correct.

There will be a handful of asynchronous methods you can call to get the user’s account. We recommend:

ethereum.send(‘eth_requestAccounts’)

ethereum.send(‘eth_accounts’)

  • This will resolve to an empty accounts array if the user has yet to connect, otherwise it resolves to a non-empty address array.

ethereum.send('wallet_requestPermissions', [{ eth_accounts: {} }])

  • Per our very own EIP 2255, you will also be able request the eth_accounts permission directly. This is what the other methods are doing under the hood. wallet_requestPermissions returns all permissions your dapp currently has. Initially, eth_accounts will be the only possible permission, but we have grand plans for this method and our new permissions system.

If your dapp calls a method with an account the user is not exposing, the inpage provider will throw an EIP 1193 authorization error, with error.code === 4100. This makes it easy for you to handle such failures.

Conclusion

In early 2020, all MetaMask provider send() calls will behave asynchronously, just as they do under the hood. They will return Promises, which will resolve directly to RPC method results. We encourage you to take a look at EIP 1102 and EIP 1193 to learn about the new APIs available to you. The new ethereum.send will be live for all other methods in the next couple of weeks, so keep an eye out for that!

--

--