Great job on the proposed changes. I am glad you considered the user-agent case, as Mist users are not protected against this kind of targeting.

But I thought about something that was sitting there even before you revisit this subject: if the majority of dapps happen to request {type: … id: 'metamask'} it would make no sense to non-Metamask DOM providers to take id into consideration and decide if it should respond to the request or not — they’d respond positively anyway.

So, to be future-proof and mitigate the risk of unnecessary fragmentation – or a potentially useless id parameter — if a dapp wants to make anything specific to metamask, instead of:

DO REQUEST METAMASK_PROVIDER
SHOW FoxWithAHat
END

It could perform:

DO REQUEST ETHEREUM_PROVIDER
IF PROVIDER === METAMASK
SHOW FoxWithAHat
END
END

Hi @everton, thanks for the feedback. The id property was originally intended to allow dapps to specify which wallet provider should service their request in scenarios where a user has multiple Ethereum extensions installed, but you’re right: this shouldn’t be codified into the proposal. If an extension or browser wishes to only respond to specific provider requests, they can establish their own proprietary API to do so (an id property being one option.)

After successful community iteration with additional browser teams and dapp developers alike, EIP-1102 has been formally updated to reflect the latest thinking on user-approved provider exposure:

Browsers expose a provider populated with no accounts by default. Before initiating any RPC request that requires an account, like eth_sendTransaction, dapps must request a full provider by calling a new provider method, provider#enable. This method triggers the user interface that allows the user to approve or deny full provider access for a given dapp. If the user approves full provider access, the provider is populated with accounts and thus fully-enabled; if the user denies full provider access, the provider is left unchanged.

This latest version of EIP-1102 avoids any previously-discussed UX issues and is now live for further review. The new protocol actively being investigated and implemented by privacy-conscious browsers including MetaMask, Mist, Status, and imToken.

Personally I preferred the event driven solution more, since it also gave an alternative to the issue when the user has multiple web3 provider enabled. But as this might not really belong in this EIP it might make sense to remove it. (But I do think “multiple installed providers” is something that needs to be thought about, especially when more standard browsers add default support, see Opera)

Another question for me would be, are there any information exposed in the read-only provider, about what provider it is? I know from some of our projects that they require meta-mask right now. So currently they check isMetaMask, but by exposing this method in the read-only provider you already give out quite some info again (or maybe not? ). I am asking this because we will probably expose a similar method for our provider and it would be nice to be consistent.

EDIT:
Why not make it possible that the injected ethereum object has information about all available providers. The dapp could then request which providers are installed and let the user choose (or if one is preferred just select that one).
When a provider tries to inject the ethereum object it checks if it exists if not it creates it. Afterwards it adds itself as a possible provider.
The flow for the dapp would stay nearly the same as right now, but it would be possible to support different providers.

Something I think was a mistake in the early designs of Ethereum was combining Ethereum network access and signing tool/credential store. I would love to take this opportunity to split the two.

A browser plug-in may provide both signing interface and Ethereum network interface, but the dapp should see them as two separate things, not a single thing.

As a dapp user, I may use some public node like Infura or a semi-private node like QuikNode for getting data from the blockchain and submitting signed transactions to the blockchain. I may then use a ledger or MetaMask for signing things.

If we take this approach, then there would be no “upgrading” your connection to full access. The Ethereum network provider would not know (or at least claim to not know) anything about your accounts/credentials and it would have no ability to sign anything. The connected signing tool on the other hand would have privacy protecting features and not give up any information (even that it exists) until the user okays it.

Hi @rmeissner, thanks for your feedback. An additional EIP could definitely specify that an object should be passed to the enable method that specifies things like a specific wallet ID, a specific account type, a specific network, etc. This may be one path to solving the “multiple installed providers” situation you mentioned, but I think it’s probably beyond the scope of this initial EIP as you suggested. Your concerns around multiple providers being injected at once are interesting; exposure protocol aside, you’re right, this is a growing issue in the ecosystem.

Also, a provider implementation can expose any non-standard method (like isMetaMask) in either read-only mode or full mode if they desire; for reference, MetaMask plans to expose the isMetaMask method in read-only mode so dapps can still react accordingly even before user-approved full access.

@MicahZoltu I agree that an ultimate separation of blockchain access and transaction signing would be very beneficial, and I think it’s a future we’re all working towards. This requires a fairly large technical shift in dapp browser architecture since most rely on exposing an augmented provider that intercepts certain RPC calls to populate accounts and to show approval UIs. We’re actively researching patterns to better separate signing interfaces from network interfaces, and thus the provider itself, but the ecosystem (and especially the user-facing dapp ecosystem) just isn’t there yet. I don’t feel that a proposal intended to standardize provider exposure and improve user privacy should determine the new paradigm for the separation of blockchain access and signers (though I’m very interested in continuing to research this more.)

(posted from a friend’s computer originally, reposting from my account)

Yes, the current (and most likely final) form of the proposal is technically a breaking change in that dapps must request a fully-enabled provider before initiating account-requiring RPC requests. But this amounts to a single additional API call; and while I see the value in the long-term goal of separating network access from signing capability, the magnitude and intent of this particular breaking change doesn’t seem to be a suitable platform for addressing this. In my mind, standardizing and restricting currently-unrestricted provider access doesn’t seem to be a valid opportunity to rethink how transaction signing works in browsers altogether.

I appreciate the feedback and hope to share ideas around the topic of network-signer separation in a new investigatory topic soon.

Hello again I’m really liking the new spec! Seems very smooth. Only point of feedback would be maybe adding a field to the provider. Something like provider#readonly, which is just a bool value.

With that the dApp wouldn’t need to ask for permission (I know the browser would cache it so you don’t have to always ask permission) if the user had already granted permission and continue on with whatever flow the dapp has.

I like the latest draft of the proposal, it simplifies the implementation considerably. I have a question about when to expect browser implementations.

As a developer, I’ve started a draft implementation of this proposal for our dApps that are in development. The cut-off date appears to be in November, but when can we expect to see the major browsers start incorporating this proposal for testing purposes?

I was hoping to see an implementation of this in Mint Browser (ie. window.ethereum doesn’t exist).

So, I have read a couple of times, and correct me if I am wrong, the main reason of this EIP is improving the user privacy and maintain user experience in a safer way. The approach followed basically allows the user to connect to “ethereum” exposing some “private” information, having in the meantime a limited provider access (the reasoning for that has been well explained few comments above). In addition, interesting discussions on this thread (leaving aside the UX conversation) have been if this EIP should contain or not a mechanism for allowing the user to obtain this full access provider using a certain wallet, and also, a couple of indications about how to improve the protocol (relying on events).

Following on the previous discussion, despite I really understand your point to keep it as simpler, effective, less intrusive, reducing at max the necessary changes to adapt dapps, I also think this EIP should provide a solution for handling multiple wallets, especially if the scope of this EIP is targeted to chrome-extensions. Or at least define how we should proceed and then stick to it.

Some reasoning and spare ideas:

Right now having “race” conditions between providers is not just not cool, seems to be kind of weird.

Modify the whole process of connecting to ethereum but leaving in a weak (in the sense of not knowing “who” has provided you full access) mode the initial part does not look right

Adding/defining a mechanism when having 1+ web3 providers is not a big deal right now, but defining a new EIP it is.

Dapp browsers can easily ignore the listeners.

One logic assumption would be if two extensions are loaded, let the user choose

Following the solutions proposed in this thread, the event-driven solution (having a way to identify the provider who fired the success event) seems to be one of the best solutions, we can create a pool (implement the event mechanism as a simple carrier state transfer) of providers easily on the frontend (we could decide if that pool should be done by wallet providers or by ourselves in the frontend) and then, apply some extensible architecture over them: like a chain of responsibility pattern or a simpler Mapper pattern. In that way:

We can create continue with the typical open to extension-close to modification way: responsibility is in one small class no big impact if changes are needed, events do not need a response and can work in a clean way.

We can choose easily provider

We know easily which available providers we have

We have less cohesive architect solutions: not compromising implementation on providers’ code, keeping them optimistic, we still code “against” more abstract solution: not specifying the id on the call when login, having third-party integrations less intrusive (events are more independent and simpler than postMessage-open-opener way)

What do you guys think? Is that something you are willing to reconsider?

hey @benzap you can already try it in latest Status.im nightly build https://status-im.github.io/nightly/
Open Status, create account and login, go to profile tab, tap Advanced and enable Dev mode , then enable web3 opt-in option and open your Dapp, feel free to contact me if you have any questions.

Hi @benzap. In addition to the Status.im nightly build that @andrey mentioned, you can also test your dapp against MetaMask by using one of the latest builds from this pull request. We also added mock 1102 support that will be available in the next MetaMask release; this means dapps can begin to call provider.enable() to update their initialization flows prior to the MetaMask 1102 release date of November 2nd, 2018.

Hi @apanizo. I agree that the issue of multiple extensions injecting (and thus overwriting) providers and Web3 instances is getting harder to ignore, especially with the growing number of extension-based wallets and signers. The issue is complex: who should decide which is the “correct” provider to use, the dapp or the user? For example, if a user has wallets A, B, and C installed as extensions and visits a dapp, should the dapp or the user choose which provider (and thus which wallet) to use for signing transactions? Since this EIP no longer changes provider injection (e.g. a provider is still injected at page load) and instead only restricts account access, I’m not sure how we could easily solve the multiple-provider issue in this proposal.

Still, the issue is a serious one. One possible solution would be a separate EIP that standardizes a <meta> tag that dapps should include. The presence of this meta tag would tell dapp browsers to inject a provider, and some attribute on the <meta> tag could indicate which provider should be injected. Something like:

<meta name="ethereum" providerID="metamask">

I think this is a complex problem that’s outside the scope of this proposal in its current form, but the <meta> tag pattern is one possible solution if dapps (and not users) should decide which provider and wallet to use.

@bitpshr@apanizo I think this is a pretty valid concern too! My opinion is that users should get to choose which provider they want. Maybe there can be some sort of mechanism where the EIP defines how providers inject themselves, but also how dapps consume them and display that info to users? I see it getting complex quickly, as maybe a user wants to change their provider for that dapp in the future… each dapp would need to implement that UI, or a fallback for just choosing one. Or maybe it can be twofold. If dapps want to control the provider, they use the meta tag. If dapps want to allow users to choose, they implement the UI. Thoughts?