EIP 1102: Opt-in account exposure Source

AuthorPaul Bouchon
Discussions-Tohttps://ethereum-magicians.org/t/eip-1102-opt-in-provider-access/414
StatusDraft
TypeStandards Track
CategoryInterface
Created2018-05-04

Simple summary

This proposal describes a way for DOM environments to expose user accounts in a way that requires user approval.

Abstract

The previous generation of Ethereum-enabled DOM environments follows a pattern of injecting a provider populated with accounts without user consent. This puts users of such environments at risk because malicious websites can use these accounts to view detailed account information and to arbitrarily initiate unwanted transactions on a user’s behalf.

This proposal outlines a protocol in which Ethereum-enabled DOM environments expose no accounts until the user approves account access.

Specification

Concepts

RFC-2119

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC-2119.

eth_requestAccounts

Providers exposed by Ethereum-enabled DOM environments define a new RPC method: eth_requestAccounts. Calling this method triggers a user interface that allows the user to approve or reject account access for a given dapp. This method returns a Promise that is resolved with an Array of accounts if the user approves access or rejected with an Error if the user rejects access.

ethereum.send('eth_requestAccounts'): Promise<string>

Provider#enable (DEPRECATED)

Note: This method is deprecated in favor of the RPC method eth_requestAccounts.

Providers exposed by Ethereum-enabled DOM environments define a new RPC method: ethereum.enable(). Calling this method triggers a user interface that allows the user to approve or reject account access for a given dapp. This method returns a Promise that is resolved with an Array of accounts if the user approves access or rejected with an Error if the user rejects access.

ethereum.enable(): Promise<any>

Protocol

Legacy dapp initialization

START dapp
IF web3 is defined
    CONTINUE dapp
IF web3 is undefined
    STOP dapp

Proposed dapp initialization

START dapp
IF provider is defined
    REQUEST[1] account access
    IF user approves
        RESOLVE[2] account access
        CONTINUE dapp
    IF user rejects
        REJECT[3] account access
        STOP dapp
IF provider is undefined
    STOP dapp
[1] REQUEST

Dapps MUST request account access by calling the eth_requestAccounts RPC method on the provider exposed at window.ethereum. Calling this method MUST trigger a user interface that allows the user to approve or reject account access for a given dapp. This method MUST return a Promise that is resolved with an array of user accounts if the user approves account access or rejected if the user rejects account access.

[2] RESOLVE

If a user approves account access, DOM environments MUST populate the provider exposed at window.ethereum with an Array of user accounts. The Promise returned when calling the eth_requestAccounts RPC method MUST be resolved with an Array of user accounts.

[3] REJECT

If a user rejects account access, the Promise returned when calling the eth_requestAccounts RPC method MUST be rejected with an informative Error.

Example initialization

try {
    // Request account access if needed
    const accounts = await ethereum.send('eth_requestAccounts');
    // Accounts now exposed, use them
    ethereum.send('eth_sendTransaction', { from: accounts[0], /* ... */ })
} catch (error) {
    // User denied account access
}

Constraints

  • Browsers MUST expose a provider at window.ethereum.
  • Browsers MUST NOT populate the provider with user accounts by default.
  • Browsers MUST define an eth_requestAccounts RPC method.
  • Browsers MUST show an account access approval UI when eth_requestAccounts is called.
  • Browsers MUST populate the provider with accounts if account access is approved.
  • Browsers MUST resolve the Promise returned by eth_requestAccounts if account access is approved.
  • Browsers MUST NOT populate the provider with accounts if account access is rejected.
  • Browsers MUST reject the Promise returned by eth_requestAccounts with an Error if account access is rejected.

Rationale

The pattern of automatic account exposure followed by the previous generation of Ethereum-enabled DOM environments fails to protect user privacy and fails to maintain safe user experience: untrusted websites can both view detailed account information and arbitrarily initiate transactions on a user’s behalf. Even though most users may reject unsolicited transactions on untrusted websites, a protocol for account access should make such unsolicited requests impossible.

This proposal establishes a new pattern wherein dapps must request access to user accounts. This protocol directly strengthens user privacy by hiding user accounts and preventing unsolicited transaction requests on untrusted sites.

Immediate value-add

  • Users can reject account access on untrusted sites to hide accounts.
  • Users can reject account access on untrusted sites to prevent unsolicited transactions.

Long-term value-add

  • Dapps could request specific account information based on user consent.
  • Dapps could request specific user information based on user consent (uPort, DIDs).
  • Dapps could request a specific network based on user consent.
  • Dapps could request multiple instances of the above based on user consent.

Backwards compatibility

This proposal impacts dapp developers and requires that they request access to user accounts following the protocol outlined above. Similarly, this proposal impacts dapp browser developers and requires that they only expose user accounts following the protocol defined above.

Implementation

The MetaMask team has implemented the strategy described above.

Copyright and related rights waived via CC0.