Deprecating “Synchronous” Provider Methods

Erik Marks
Oct 31 · 3 min read

This is one of the breaking changes we’re making on January 13, 2020. Click here for more details.

This story originally listed an incorrect, earlier deprecation date.

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 on January 13, 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). These new APIs will go live during the week of November 25, 2019. All existing ways of sending RPC requests will still work.

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 go live during the week of November 25, 2019. It 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

Starting January 13, 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!

MetaMask

MetaMask is a bridge that allows you to visit the distributed web of tomorrow in your browser today. It allows you to run Ethereum dApps right in your browser without running a full Ethereum node.

Erik Marks

Written by

Developer at MetaMask. Lagom in all things.

MetaMask

MetaMask

MetaMask is a bridge that allows you to visit the distributed web of tomorrow in your browser today. It allows you to run Ethereum dApps right in your browser without running a full Ethereum node.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade