DCIPs/EIPS/eip-1102.md

139 lines
6.0 KiB
Markdown

---
eip: 1102
title: Opt-in account exposure
author: Paul Bouchon <mail@bitpshr.net>, Erik Marks (@rekmarks)
discussions-to: https://ethereum-magicians.org/t/eip-1102-opt-in-provider-access/414
status: Stagnant
type: Standards Track
category: Interface
created: 2018-05-04
requires: 1474
---
## Simple summary
This proposal describes a communication protocol between dapps and Ethereum-enabled DOM environments that allows the Ethereum-enabled DOM environment to choose what information to supply the dapp with and when.
## 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 can choose to 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](https://www.ietf.org/rfc/rfc2119.txt).
#### `eth_requestAccounts`
Providers exposed by Ethereum-enabled DOM environments define a new RPC method: `eth_requestAccounts`. Calling this method may trigger 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 or is rejected with an `Error` if accounts are not available.
```typescript
ethereum.send('eth_requestAccounts'): Promise<Array<string>>
```
#### Provider#enable (DEPRECATED)
**Note: This method is deprecated in favor of the RPC method [`eth_requestAccounts`](#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.
```typescript
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 accounts by calling the `eth_requestAccounts` RPC method on the provider exposed at `window.ethereum`. Calling this method **MAY** 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 one or more user accounts or rejected if no accounts are available (e.g., the user rejected account access).
##### `[2] RESOLVE`
The `Promise` returned when calling the `eth_requestAccounts` RPC method **MUST** be resolved with an `Array` of user accounts.
##### `[3] REJECT`
The `Promise` returned when calling the `eth_requestAccounts` RPC method **MUST** be rejected with an informative `Error` if no accounts are available for any reason.
### Example initialization
```js
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** define an `eth_requestAccounts` RPC method.
* Browsers **MAY** wait for a user interaction before resolving/rejecting the `eth_requestAccounts` promise.
* Browsers **MUST** include at least one account if the `eth_requestAccounts` promise is resolved.
* Browsers **MUST** reject the promise with an informative error if no accounts are available.
## 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 allowing the browser to hide 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](https://github.com/MetaMask/metamask-extension/pull/4703) the strategy described above.
## Copyright
Copyright and related rights waived via [CC0](../LICENSE.md).