Closed rekmarks closed 3 years ago
Hi, does the current version 7.7.7 support the new api?
When I try to use ethereum.send('eth_requestAccounts')
replace ethereum.enable()
, metamask returns {code: -32601, message: "The method undefined does not exist/is not available"}
.
Hi @imnisen, the new API is not live; no production version of MetaMask supports it. It will say in this issue when it is.
Any recommended ways to test that my site will not be affected by this as a Dapp developer?
@bhayward93, if you subscribe to this issue and follow us on Twitter you'll be notified when we have a build with only the new API ready. We'll provide instructions for how to test it, and you'll have a full 6 weeks to do it.
Hi @imnisen, the new API is not live; no production version of MetaMask supports it. It will say in this issue when it is.
Hey @rekmarks @danfinlay can we get a status update? It looks as though this may be live or partially live. Also, I read in the docs that the plan is to be compliant with EIP 1193, however, EIP 1193 deprecates the send
method entirely, preferring request
. The docs do not show a request
method in the new api. Will it be supported?
Thanks!
Hi @dmvt, thanks for reaching out.
We are indeed aware of the updates to EIP 1193, because I wrote the PR that deprecated send
in favor of a new method, request
.
The updates to EIP 1193 followed discussions by the original authors of that EIP, convenience library authors (ethers
, web3
), dapp developers, and other community members. They were designed to make the new API less breaking for dapps and convenience libraries, and easier to implement for wallets.
Our documentation and the above Medium articles will be updated to reflect the new changes sometime tomorrow, April 6, Pacific Time.
The ship date for the new API is still TBD, and this issue will be updated accordingly.
Hello all, is there perhaps a timeline we can refer to regarding the new API? Looking to understand when we're going to need to have resources to build out the new support.
I agree with @crazyrabbitLTC, we would appreciate a timeline, since it said early 2020. Now, we are almost in Mid 2020.
Very much in the same boat as @crazyrabbitLTC and @alextreib here. Further details highlighting a predicted timeline would be much appreciated, even if not totally accurate, since we can then roughly allocate resources.
We are finally able to give an update about this!
Stop using window.web3
and use window.ethereum
or ethers
instead. If using window.ethereum
, target this API, which will be available soon, in version 8.0.0
. If you're already using window.ethereum
, you may have to make some minor changes in the next few months.
window.web3
object injected by MetaMask, you are going to have to make changes by the end of August (2020-08-31), or your dapp will break.
window.ethereum
or ethers
, ASAP.window.ethereum
object injected by MetaMask, you may have to make changes in the next few months. Read on for details.ethers
, you don't have to do anything except keep it up to date. web3
should mostly be fine too. If you use a convenience library, we recommend ethers
.We will ship a non-breaking update that includes the new Provider API in the next few weeks, 8.0.0
, and will make an announcement when the time comes. Read on for details.
window.ethereum
) will not undergo any breaking changes, except for a misnamed event and two experimental methods under ethereum._metamask
.chainIdChanged
, and instead emit chainChanged
ethereum._metamask.isEnabled
ethereum._metamask.isApproved
web3
into web pagesWe will ship the new Provider API in the next few weeks, without any breaking changes, and will make an announcement when the time comes.
After our original announcement, there was a movement to make further changes to the standard defining the Provider API, EIP 1193. We were deeply involved in writing those updates, and helped create a version that is non-breaking. This means that, if you rely on ethereum.send
or ethereum.sendAsync
today, they will continue to work. Nevertheless, we think the new API is pretty sweet, and offers some cool features, and we recommend that you check it out here.
@rekmarks when this new api will be released? as new dapps also need to use old API currently. so if you can provide timeline, it would be very helpful.
@rekmarks I have updated MetaMask extension to v7.7.9 and still get old-signature method ethereum.send(payload, callback)
at some pages instead of new ethereum.send(method: string, params: Array<any>)
at other pages. What can cause different versions MetaMask APIs injecting?
@aksdevac, as early as next week, but probably the week of May 18, 2020.
For everyone's knowledge, the issue raised by @Kharabet was due to web3@1.x
overwriting ethereum.send
. This will not happen with ethereum.request
, which will throw an error on overwrite attempts via a Proxy.
Thanks for the detailed update @rekmarks!
I'm curious - why the decision to "stop reloading the page on network change"? This is something convenience libraries (like ethers
) will not be able to easily handle. I agree with Richard Moore's comment here on why MetaMask should continue to reload the page on network change.
@samajammin It's more hassle for the developer but it provides better end-user UX. It allows the user to keep their app state and not lose context. Regarding Ethers.js (it's essentially the same issue w/ Web3.js), you simply acquire a new provider once you get the event.
Here's some recent code I worked on just the other day to do this w/ React hooks:
// re-register MetaMask provider whenever network changes
useEffect(() => {
window.ethereum.on("chainChanged", (network) => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
setProvider(provider)
});
}, [provider]);
For everyone's knowledge, the issue raised by @Kharabet was due to web3@1.x overwriting ethereum.send. This will not happen with ethereum.request, which will throw an error on overwrite attempts via a Proxy.
@rekmarks is there currently any way to prevent this from happening? Will switching to request
be the only way to avoid this going forward?
@samajammin, thanks! Regarding reloading on network change, I think @ricmoo makes a convincing argument that it's often a good idea to do so, but we (MetaMask) don't believe that we should make that choice for others.
Regarding changing networks and the average user, it is not true that only dapp devs use test networks, as evidenced by e.g. Reddit's rewards. We're definitely open to the idea of a "dev mode" in MetaMask in the future, but believe that our users are already protected because:
This [not reloading on network change] is something convenience libraries (like
ethers
) will not be able to easily handle.
With the new Provider API, library and dapp developers can implement this with a single line:
ethereum.on('chainChanged', () => window.location.reload())
I fully support anyone that wants to continue reloading pages on network changes, we're just not going to force that behavior on you by default. We'll continue to recommend ethers
regardless!
@balasan, AFAIK, there's no way to prevent web3@1.x
from overwriting ethereum.send
at the moment, other than not using web3@1.x
. The version injected by MetaMask β which, I'll repeat, everyone should stop using immediately because we are going to stop injecting it later this year β does not overwrite ethereum.send
.
ethereum.request
is absolutely the recommended method going forward. ~Our provider will throw an error if an overwrite of ethereum.request
is attempted, and deletions will be ignored.~
Please keep the web3 API alive as long as the ethereum isn't completely defined and has bugs.
@alextreib we wonβt start the 3-month web3
deprecation period until EIP-1193 has been finalized. At the moment, it looks like this will happen on 2020-06-04. Either way, it will be announced here.
Regardless of 1193, you should stop using our injected version of web3
today. We recommend ethers
.
Sorry... Late to the game. I'm writing the docs on the best way to restore the behaviour of reloading the page in the "best practices" section of the docs right now. :)
So chiming in with my two cents, feel free to disregard, but this exact thing is leading to other issues, which are terribly difficult to solve (possibly undecidable) in a generic way.
I think the default of reloading still makes sense. It is fine to allow an option to override this behaviour for advanced cases where that makes sense, especially in developer tools (e.g. remix would likely want to handle this).
I would also say that unless the developer is explicitly listening to the "chainChanged" event, the behaviour should not be able to be changed from this default refresh. If a developer is not explicitly listening for the network to change, they are likely not equipped to handle it. If they really know what they are doing, they can register with an empty callback.
I guess I wonder what the value for the default behaviour to not refresh is? As long as there is a way for a developer to announce they are advanced and wish to tackle the nuances, that should be fine. Refreshing ensures any app (ish) works in general across networks, even for inexperience (and more importantly non-veteran) developers. Not refreshing can lead to lost funds, leaking data and inconsistent non-atomic operations.
I'll just give a few examples of small things that become very hard to handle if a dapp developer doesn't fully understand the consequences and minutia of handling a network change (at which time they are responsible to unregister all listeners, purge all caches, and re-register for events, handle in-flight activities).
Basically, Turing Complete is hard to deal with. So, the default should be as safe as possible, for the widest audience of developers, and people who want the additional exercise, may do so, but opt-in for it.
That's my protest for now. :)
I would also like to throw my voice in with regards to refreshing the page. As long as people can switch providers, which often leads to unpredictable outcomes, I also think we should refresh the page. It's so very hard to keep in sync with a network that is changing, non-deterministic, with nodes that might return conflicting data that allowing the user to change networks suddenly without reloading the page just adds to the weight of developers trying to catch edge cases. Sure it's not a nice experience, but if you're changing the network, you're doing something pretty dramatic. It's like connecting to a whole different internet.
So, just another voice.
Yeah, we discussed this extensively internally, and are working out a plan for what to with our default behavior. I don't want to make any premature announcements, but unless you have an extremely good reason to handle network changes without refreshing the page, our official recommendation is to do:
ethereum.on('chainChanged', () => window.location.reload())
but unless you have an extremely good reason to handle network changes without refreshing the page, our official recommendation is to do:
ethereum.on('chainChanged', () => window.location.reload())
This makes me think that this API is designed for the least frequent use-case by default. Won't this lead to the majority of apps accidentally breaking? Not talking just of existing ones, but also new ones.
I think giving devs the possibility of not having their pages reloaded on network changes is really important. I'm glad you are adding that. I just worry that it may be yet another hard-to-discover gotcha of the Ethereum platform.
I would also say that unless the developer is explicitly listening to the "chainChanged" event, the behaviour should not be able to be changed from this default refresh.
This idea is really interesting.
Alright, here's the complete context:
After discussing it internally, we were convinced by @ricmoo's argument above, that the default behavior should be that the page is reloaded. I also agree with the points raised by @crazyrabbitLTC and @alcuadrado. We also want consumers to be able to override the reload, if they wish.
Now, the problem is that we don't reload by default under most circumstances, at the moment. We only reload by default if our injected window.web3
object has been accessed. (Don't ask why. π) What we want to do is reload if our window.ethereum
object, the provider, has been accessed.
That being the case, enabling reload by default would probably be breaking for existing dapps. Probably not catastrophically breaking, but breaking nonetheless. That being the case, we need to go through a deprecation process. We'll most likely add it to the first round of changes noted previously in this thread, 6 weeks after the launch of MetaMask v8.
Regarding how to override the default, the majority opinion on the team is to have an explicit toggle (e.g. ethereum.stopReloadOnNetworkChange()
), rather than an implicit one (e.g. adding a chainChanged
listener).
Random idea... Not sure if it's good or not, but just thinking out loud. Rather than having functions on the ethereum object, use something like: ethereum.request("com.metamask_stopReloadOnNetworkChange", [])
?
I would also like to start (or help start?) an EIP on vendor extensions, like this. I also plan to update EIP-634 to use a similar reverse dot notation, so there is no central registry required, while preserving hierarchal vendor types.
I am at a loss to find docs on ethereum.request
. Can someone please refer me? Thanks!
I am at a loss to find docs on
ethereum.request
. Can someone please refer me? Thanks!
Found some: https://eips.ethereum.org/EIPS/eip-1193#request
(slightly adjacent topic) I just want to throw this in here in case the right person sees this - are there any community adopted TypeScript typings around the ethereum
object that exist today and would be expected to be upgraded as this issue and associated EIP develops?
What should developers do that were using the web3.js 0.2 version that was being injected? I was using this to sign transactions directly using the PK.
@rekmarks Maybe this status needs an update.
The New API is: Not Live
Looks like it is partially live. I can currently use ethereum.request({ method: 'eth_requestAccounts' })
on Firefox but not yet on Chrome.
The MetaMask docs show a rollout warning.
The new API is live on Chrome and Firefox. Please see the original issue comment for details. We do have upcoming breaking changes, so please make sure to read it.
It's also MetaMask's 4th birthday (π¦), and Bastille Day (π«π·). Happy birthday to us, and bonne fΓͺte nationale to the French!
Reposting latest announcement for great email notification convenience:
The new Provider API is live in MetaMask 8.0.4 on Chrome and Firefox as of 2020-07-14, which happens to be MetaMask's 4th birthday π .
Please consult our documentation to learn how to use the API.
The new API should be non-breaking for all dapps. If your dapp is broken, it is an all likelihood a bug. Please file a bug report if so.
We are still going to make some breaking changes to our provider. These include:
eth_chainId
return valueschainIdChanged
, and instead emit chainChanged
ethereum._metamask.isEnabled
ethereum._metamask.isApproved
We are also still going to remove our injected window.web3
.
Please see the relevant section of our documentation for details. You can migrate to protect yourself from these changes today. Please see our migration guide for details. We will announce dates soon, but there's no reason to wait. Migrate today!
Since MetaMask v8 launched, we noticed that the ethereum.publicConfigStore
object is being used by some consumers. We've also seen it accessed as web3.currentProvider.publicConfigStore
.
Despite its name, the publicConfigStore
object was never intended for public consumption, and it is scheduled for removal along with the other window.ethereum
API changes mentioned in the original issue comment (which has been updated with this removal).
Everything you can do with the publicConfigStore
can be done at least as easily via other properties / events / methods / public state etc. If you are using the publicConfigStore
, please review why, and replace it with the corresponding APIs in our documentation.
Metamask in our app stopped working today with 8.07
. I thought compatibility breaking changes were planned on 30 of August?
Could there be a bug in the 8.07
version of the extension? I'm getting in console:
inpage.js:1 MetaMask: 'ethereum.enable()' is deprecated and may be removed in the future. Please use the 'eth_requestAccounts' RPC method instead.
For more information, see: https://eips.ethereum.org/EIPS/eip-1102
And then just no response in the window.ethereum.enable()
, not even a rejection
const ethereumProvider: EthereumProvider = (<any>window).ethereum || null;
const whenAccounts = Promise.resolve()
.then(() => ethereumProvider.send('eth_requestAccounts'))
.catch(exc => {
console.warn('eth_requestAccounts failed, possibly metamask version is < 8.0.7, falling back to legacy .enable()', exc);
return ethereumProvider.enable();
});
const accounts = await addTimeout(30 * 1000, whenAccounts);
Also, the proposed ethereum.send('eth_requestAccounts')
from eip-1102 does not seem to work either:
TypeError: Cannot create property 'jsonrpc' on string 'eth_requestAccounts'
at t.exports._rpcRequest (inpage.js:1)
at t.exports.sendAsync (inpage.js:1)
at eval (LoginManagerMatic.vue?7c02:178)
(note, judging by https://github.com/MetaMask/metamask-docs/issues/40, there is a mistake in the docs?)
Upd.: yeah, thanks, seems to be specific to our dapp configuration, maybe our global web3 script import
@klesun I was unable to reproduce your issue locally using 8.0.7. We have not yet made any breaking changes to the provider API.
I recommend trying ethereum.request({ method: 'eth_requestAccounts' })
instead of ethereum.send
or ethereum.enable
. Please create a separate issue if the problem persists!
@karega, to answer your question about what to do if you're using the injected window.web3
, please see our migration guide. I apologize for the delayed response!
Though 8.0.6
did work with our dapp ok today, checked on 4 pcs with and without the update, so I take it that some breaking changes were introduced in 8.0.7
. I'll update my comment when I find the cause.
Got the stack trace, here is the issue: https://github.com/MetaMask/metamask-extension/issues/9234
Upd.: this seems to be related to mutation observer/proxy of window.web3
when you assign it to a field in a Vue component due to reactive properties in my case
@klesun That's strange, because we didn't ship any changes to the provider in 8.0.7. See: https://github.com/MetaMask/metamask-extension/compare/v8.0.6...v8.0.7
We'd love to understand what the problem is, but please create a new issue instead of updating your previous comment.
The breaking changes will ship on or shortly after November 16, 2020. Please see the original issue comment for details.
As announced previously, the new API is live, as are tools for moving off our injected window.web3
. There's no reason to wait, migrate today!
If you want to try out your dapp with a version of MetaMask that does not inject window.web3
, you can grab the latest build from #9156 (posted automatically by @metamaskbot) and follow the instructions in our README for loading a custom build of MetaMask.
Please remember to only load custom MetaMask builds from trusted sources, like our GitHub.
Regarding eth_chainId the check } else if (chainId !== endpointChainId) {
in network-form.component.js seems is using strings and thus is very brittle. Any thought on converting the hex to numbers before the comparison, so that numbers are compared and not formatted strings?
Not sure about other node implementations, but our node implementation is/was returning 0 padded hex strings, and we will have to change that otherwise the comparison will fail, even though the numeric value is the same (Diode prenet chain_id = 15) https://chainid.network/ Corresponding change to stay compatible: https://github.com/diodechain/diode_server_ex/commit/5d4ac2c35c61d5354a3bd97f727a39362522da17
@dominicletz I sympathize with your point, but it is brittle by design. We do not want to be in a position where we or consumers of our provider API have to parse chainId
values. I'll refer to EIP-695 - which specifies the eth_chainId
RPC method - and the Ethereum JSON-RPC API, which specifies data types for Ethereum JSON-RPC methods.
You'll note that, per EIP-695, the chainId
value is a QUANTITY
, which the Ethereum JSON-RPC API states must not have leading zeros (see the "HEX value encoding" heading in the second link above).
@dominicletz I sympathize with your point, but it is brittle by design. We do not want to be in a position where we or consumers of our provider API have to parse
chainId
values. I'll refer to EIP-695 - which specifies theeth_chainId
RPC method - and the Ethereum JSON-RPC API, which specifies data types for Ethereum JSON-RPC methods.You'll note that, per EIP-695, the
chainId
value is aQUANTITY
, which the Ethereum JSON-RPC API states must not have leading zeros (see the "HEX value encoding" heading in the second link above).
Uh! Thanks for that note, wasn't even aware.
You're very welcome, thanks for understanding!
After doing all the migration updates mentioned and trying to send the transaction, metamask pops-up but when I click confirm, the website is not able to get the transaction hash from MM.
I used the same code as mentioned on the MM Docs, i.e,
const txHash = await ethereum.request({ method: 'eth_sendTransaction', params: [transactionParameters], });
also, this random error is being poping up on Dev Console:
ERROR Error: Uncaught (in promise): TypeError: this._processRequest(...).catch(...).finally is not a function TypeError: this._processRequest(...).catch(...).finally is not a function at e._handle (inpage.js:15) at e.handle (inpage.js:15) at t.exports._rpcRequest (inpage.js:1) at inpage.js:1 at new ZoneAwarePromise (zone.js:875) at t.exports.request (inpage.js:1) at Web3Service.<anonymous> (web3.service.ts:1452)
at line 1452, on web3service, we have:
window['ethereum'].request({ method: 'eth_sendTransaction', params: [ { to: <Address>, from: <currentWallet>, value: "0x0", data: <encodedData> }, ], }).then((txHash) => console.log(txHash)) .catch((error) => console.error);
Any help/input would be amazing
@rekmarks
On this migration, For interacting with Contract on the Angular website we used to do it like this:
this.web3.eth.contract(<abi>).at(<address>)
& then use the contract-instance object to interact, but with the MM migration, how do we go about doing the contract interaction??
Also, I updated my implementation to use ethereum.request({method: 'eth_sendTransaction',params: []})
, but, when I use it now, it doesn't work and gives me the below error:
e.abi.filter is not a function at c (inpage.js:15)
Also, I have multiple places where contract interaction occurs, any help or guidance would be amazing :)
Just want to understand this contract interaction bit after MM migration.
EDIT: When I do the same things on Ropsten network, all works. MM pops-up and then I can interact and do my transaction. but on Mainnet it shows this error only for a particular function on the contract, rest all other other contract interactions work.
EDIT 2: Solved the issue.
It is now November 16, and we will stop injecting window.web3
and ship the breaking changes to our window.ethereum
API in an upcoming release.
Due to app store review processes, we canβt say exactly when the changes will go live, but you should no longer rely on any of the affected features, as they may break at any time. Both the MetaMask browser extension and mobile app will be affected.
We will make an announcement here when the changes have started to roll out, along with the version number that includes the changes.
Thanks for your heads up.
The Breaking Changes are Live
As of version
9.0.2
of the MetaMask extension (and1.0.9
of MetaMask Mobile), the breaking changes are live. See the migration guide for more details.The below information is only useful for historical purposes.
Summary
We are removing
window.web3
and making some breaking changes towindow.ethereum
. These changes apply to all version of MetaMask (extension and mobile).We committed to maintaining the affected features until November 16, 2020. That day has now come, and the changes may ship at any time. Due to app store review processes, we can't say exactly when, but we will make an announcement here once we know for sure.
New Provider API
We shipped a new, non-breaking Provider (
window.ethereum
) API in MetaMask 8.0.4 on July 14, 2020, which happened to be MetaMask's 4th birthday π π¦ π. This API is also available through MetaMask mobile.Please consult our documentation to learn how to use the API.
Upcoming Breaking Changes
These changes will ship on or after November 16, 2020. The version number of MetaMask that includes the breaking changes will be announced by this date.
window.web3
RemovalWe are going to remove our injected
window.web3
. See #7163 for why, and our migration guide for replacement strategies.See #9156 for the latest build without
window.web3
, automatically posted by @metamaskbot.window.ethereum
API ChangesWe are also going to make some breaking changes to our provider. These include:
eth_chainId
return valueschainIdChanged
, and instead emitchainChanged
ethereum.publicConfigStore
ethereum._metamask.isEnabled
ethereum._metamask.isApproved
What to Do Next
Please see the relevant section of our documentation for details. You can migrate to protect yourself from these changes today. Please see our migration guide for details. There's no reason to wait, migrate today!