Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1193: Make spec availability-agnostic #2588

Merged
merged 3 commits into from
Apr 8, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 30 additions & 14 deletions EIPS/eip-1193.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ requires: 155, 695, 1102, 1474, 1767

This EIP formalizes a JavaScript Ethereum Provider API for consistency across clients and applications.

The Provider is intended to be available as `globalThis.ethereum` (i.e. `window.ethereum` in browsers), so that JavaScript dapps can be written once and function in perpetuity.

The Provider's interface is designed to be minimal, preferring that features are introduced in the API layer (e.g. see [`eth_requestAccounts`](https://eips.ethereum.org/EIPS/eip-1102)), and agnostic of transport and RPC protocols.

Historically, Providers have been made available as `window.ethereum` in web browsers, but this convention is not part of the specification.

The events `connect`, `disconnect`, `chainChanged`, and `accountsChanged` are provided as a convenience to help enable reactive dapp UIs.

## API
Expand All @@ -29,13 +29,13 @@ Makes an Ethereum RPC method call.
```typescript
type RequestParams = Array<any> | { [key: string]: any };

ethereum.request(method: string, params?: RequestParams): Promise<unknown>;
Provider.request(method: string, params?: RequestParams): Promise<unknown>;
rekmarks marked this conversation as resolved.
Show resolved Hide resolved
```

The Promise resolves with the method's result or rejects with a [`ProviderRpcError`](#errors). For example:

```javascript
ethereum
Provider
.request('eth_accounts')
.then((accounts) => console.log(accounts))
.catch((error) => console.error(error));
Expand All @@ -59,7 +59,7 @@ This method is deprecated in favor of [`request`](#request).
`sendAsync` is like `request`, but with JSON-RPC objects and a callback.

```typescript
ethereum.sendAsync(request: Object, callback: Function): Object;
Provider.sendAsync(request: Object, callback: Function): void;
```

The interfaces of request and response objects are not specified here.
Expand All @@ -70,7 +70,7 @@ Historically, they have followed the [Ethereum JSON-RPC specification](https://g
This method is deprecated in favor of [`request`](#request).

```typescript
ethereum.send(...args: Array<any>): unknown;
Provider.send(...args: Array<any>): unknown;
```

### Events
Expand All @@ -90,7 +90,7 @@ interface ProviderConnectInfo {
[key: string]: unknown;
}

ethereum.on('connect', listener: (connectInfo: ProviderConnectInfo) => void): ethereum;
Provider.on('connect', listener: (connectInfo: ProviderConnectInfo) => void): Provider;
```

The event emits an object with a hexadecimal string `chainId` per the `eth_chainId` Ethereum RPC method, and other properties as determined by the Provider.
Expand All @@ -100,7 +100,7 @@ The event emits an object with a hexadecimal string `chainId` per the `eth_chain
The Provider emits `disconnect` when it becomes disconnected from all chains.

```typescript
ethereum.on('disconnect', listener: (error: ProviderRpcError) => void): ethereum;
Provider.on('disconnect', listener: (error: ProviderRpcError) => void): Provider;
```

This event emits a [`ProviderRpcError`](#errors). The error `code` follows the table of [`CloseEvent` status codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes).
Expand All @@ -114,7 +114,7 @@ This event is deprecated in favor of [`disconnect`](#disconnect).
The Provider emits `chainChanged` when connecting to a new chain.

```typescript
ethereum.on('chainChanged', listener: (chainId: string) => void): ethereum;
Provider.on('chainChanged', listener: (chainId: string) => void): Provider;
```

The event emits a hexadecimal string `chainId` per the `eth_chainId` Ethereum RPC method.
Expand All @@ -130,7 +130,7 @@ For details, see [EIP 155: Simple replay attack protection](https://eips.ethereu
The Provider emits `accountsChanged` if the accounts returned from the Provider (`eth_accounts`) change.

```typescript
ethereum.on('accountsChanged', listener: (accounts: Array<string>) => void): ethereum;
Provider.on('accountsChanged', listener: (accounts: Array<string>) => void): Provider;
```

The event emits with `accounts`, an array of account addresses, per the `eth_accounts` Ethereum RPC method.
Expand All @@ -146,7 +146,7 @@ interface ProviderMessage {
data: unknown;
}

ethereum.on('message', listener: (notification: ProviderMessage) => void): Provider;
Provider.on('message', listener: (notification: ProviderMessage) => void): Provider;
```

##### Subscriptions
Expand Down Expand Up @@ -174,7 +174,12 @@ interface ProviderRpcError extends Error {

## Examples

> These examples assume a web browser environment.
```javascript
// The Provider will usually be available as window.ethereum on page load.
// This is only a convention, not a standard, and may not be the case in practice.
// Please consult the Provider implementation's documentation.
const ethereum = window.ethereum;

// A) Set Provider in web3.js
Expand Down Expand Up @@ -277,9 +282,20 @@ _This section is non-normative._

### Availability

In a browser environment, the Provider **MUST** be made available as the `ethereum` property on the global `window` object.
_This section is non-normative._

How the Provider is made available to consumers is beyond the scope of this specification.
At the time of writing, there exists no specification for Provider availability, merely a convention.
This convention is described here for the benefit of dapp developers and Provider implementers.

Historically, Providers have been injected into web pages as `window.ethereum` (more generally, `globalThis.ethereum`), such that they are available on page load.

In practice, this convention does not handle some situations, including:

- Multiple Providers being injected into the same page, e.g. when the user has multiple wallets installed
- Asynchronously injected Providers, whether by choice or due to platform limitations

In a non-browser environment, the Provider **SHOULD** be made available as the `ethereum` property on the `globalThis` object.
Provider implementers are encouraged to work with each other and with dapp developers to solve these problems until standards emerge.

### Connectivity

Expand All @@ -301,7 +317,7 @@ The Provider **MAY** expose methods and properties not specified in this documen
```typescript
type RequestParams = Array<any> | { [key: string]: any };

ethereum.request(method: string, params?: RequestParams): Promise<unknown>;
Provider.request(method: string, params?: RequestParams): Promise<unknown>;
```

The `request` method is intended as a transport- and protocol-agnostic wrapper function for Remote Procedure Calls (RPCs).
Expand Down