diff --git a/EIPS/eip-1193.md b/EIPS/eip-1193.md index b828986081bf3d..85cdb83e4871ed 100644 --- a/EIPS/eip-1193.md +++ b/EIPS/eip-1193.md @@ -18,7 +18,7 @@ The Provider is intended to be available as `globalThis.ethereum` (i.e. `window. 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. -The events `connect`, `close`, `chainChanged`, and `accountsChanged` are provided as a convenience to help enable reactive dapp UIs. +The events `connect`, `disconnect`, `chainChanged`, and `accountsChanged` are provided as a convenience to help enable reactive dapp UIs. ## API @@ -32,7 +32,7 @@ type RequestParams = Array | { [key: string]: any }; ethereum.request(method: string, params?: RequestParams): Promise; ``` -The Promise resolves with the method's result or rejects with an `Error`. For example: +The Promise resolves with the method's result or rejects with a [`ProviderRpcError`](#errors). For example: ```javascript ethereum @@ -44,18 +44,6 @@ ethereum Consult each Ethereum RPC method's documentation for its return type. You can find a list of common methods [here](https://eips.ethereum.org/EIPS/eip-1474). -The Promise rejects with errors of the following form: - -```typescript -{ - message: string, - code: number, - data?: any -} -``` - -See the [RPC Errors](#rpc-errors) section for more details. - #### RPC Protocols Multiple RPC protocols may be available. @@ -66,8 +54,9 @@ Multiple RPC protocols may be available. ### sendAsync (DEPRECATED) -Submits a JSON-RPC request to the Provider. -As [`ethereum.request`](#request), but with JSON-RPC objects and a callback. +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; @@ -78,7 +67,7 @@ Historically, they have followed the [Ethereum JSON-RPC specification](https://g ### send (DEPRECATED) -Due to conflicting implementations and specifications, this method is unreliable and should not be used. +This method is deprecated in favor of [`request`](#request). ```typescript ethereum.send(...args: Array): unknown; @@ -93,7 +82,7 @@ Events follow the [Node.js `EventEmitter`](https://nodejs.org/api/events.html) A The Provider emits `connect` when it: - first connects to a chain after being initialized. -- first connects to a chain, after the `close` event was emitted. +- first connects to a chain, after the `disconnect` event was emitted. ```typescript interface ProviderConnectInfo { @@ -106,15 +95,19 @@ ethereum.on('connect', listener: (connectInfo: ProviderConnectInfo) => void): et 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. -#### close +#### disconnect -The Provider emits `close` when it becomes disconnected from all chains. +The Provider emits `disconnect` when it becomes disconnected from all chains. ```typescript -ethereum.on('close', listener: (code: number, reason: string) => void): ethereum; +ethereum.on('disconnect', listener: (error: ProviderRpcError) => void): ethereum; ``` -This event emits with `code` and `reason`. The code follows the table of [`CloseEvent` status codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes). +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). + +#### close (DEPRECATED) + +This event is deprecated in favor of [`disconnect`](#disconnect). #### chainChanged @@ -128,7 +121,9 @@ The event emits a hexadecimal string `chainId` per the `eth_chainId` Ethereum RP #### networkChanged (DEPRECATED) -The event `networkChanged` is deprecated in favor of `chainChanged`. For details, see [EIP 155: Simple replay attack protection](https://eips.ethereum.org/EIPS/eip-155) and [EIP 695: Create eth_chainId method for JSON-RPC](https://eips.ethereum.org/EIPS/eip-695). +The event `networkChanged` is deprecated in favor of [`chainChanged`](#chainchanged). + +For details, see [EIP 155: Simple replay attack protection](https://eips.ethereum.org/EIPS/eip-155) and [EIP 695: Create eth_chainId method for JSON-RPC](https://eips.ethereum.org/EIPS/eip-695). #### accountsChanged @@ -163,9 +158,19 @@ For e.g. `eth_subscribe` subscription updates, `ProviderMessage.type` will equal #### notification (DEPRECATED) -This event should not be relied upon, and may not be implemented. +This event is deprecated in favor of [`message`](#message). -Historically, it has returned e.g. `eth_subscribe` subscription updates of the form `{ subscription: string, result: unknown }`. +Historically, this event has returned e.g. `eth_subscribe` subscription updates of the form `{ subscription: string, result: unknown }`. + +### Errors + +```typescript +interface ProviderRpcError extends Error { + message: string; + code: number; + data?: any; +} +``` ## Examples @@ -248,7 +253,7 @@ ethereum.on('accountsChanged', logAccounts); ethereum.removeListener('accountsChanged', logAccounts); // Example 6: Log if connection ends -ethereum.on('close', (code, reason) => { +ethereum.on('disconnect', (code, reason) => { console.log(`Ethereum Provider connection closed: ${reason}. Code: ${code}`); }); ``` @@ -257,14 +262,16 @@ ethereum.on('close', (code, reason) => { 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). +> Comments like this are non-normative. + ### Definitions -> This section is non-normative. +_This section is non-normative._ - Provider - - A JavaScript object made available to a dapp, that provides access to Ethereum by means of a Client + - A JavaScript object made available to a dapp, that provides access to Ethereum by means of a Client. - Client - - An endpoint accessed by a Provider, that receives Remote Procedure Call (RPC) requests and returns their results + - An endpoint accessed by a Provider, that receives Remote Procedure Call (RPC) requests and returns their results. - Remote Procedure Call (RPC) - A Remote Procedure Call (RPC), is any request submitted to a Provider for some procedure that is to be processed by a Provider or its Client. @@ -274,6 +281,15 @@ In a browser environment, the Provider **MUST** be made available as the `ethere In a non-browser environment, the Provider **SHOULD** be made available as the `ethereum` property on the `globalThis` object. +### Connectivity + +The Provider is said to be "connected" when it can service RPC requests to any chain. + +The Provider is said to "disconnected" when it cannot service RPC requests to any chain. + +> To service an RPC request, the Provider must successfully submit the request to the remote location, and receive a response. +> In other words, if the Provider is unable to communicate with its Client, for example due to network issues, the Provider is disconnected. + ### API The Provider **MUST** expose the API defined in this section. All API entities **MUST** adhere to the types and interfaces defined in this section. @@ -299,15 +315,24 @@ If resolved, the Promise **MUST NOT** resolve with any RPC protocol-specific res If resolved, the Promise **MUST** resolve with a result per the RPC method's specification. -If the returned Promise rejects, it **MUST** reject with an `Error` of the form specified in the [RPC Errors](#rpc-errors) section below. +If the returned Promise rejects, it **MUST** reject with a `ProviderRpcError` as specified in the [RPC Errors](#rpc-errors) section below. The returned Promise **MUST** reject if any of the following conditions are met: -- The client returns an error for the RPC request - - If error returned from the client is compatible with the `ProviderRpcError` interface, the Promise **MAY** reject with that error directly -- The Provider encounters an fails for any reason -- The request requires access to an unauthorized account, per [EIP 1102](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md) - - In this case, the Promise rejection error `code` **MUST** be `4100` +- The client returns an error for the RPC request. + - If error returned from the client is compatible with the `ProviderRpcError` interface, the Promise **MAY** reject with that error directly. +- The Provider encounters an fails for any reason. +- The request requires access to an unauthorized account, per [EIP 1102](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1102.md). + - If rejecting for this reason, the Promise rejection error `code` **MUST** be `4100`. + +The returned Promise **SHOULD** reject if any of the following conditions are met: + +- The Provider is disconnected. + - If rejecting for this reason, the Promise rejection error `code` **MUST** be `4900`. +- The RPC request is directed at a specific chain, and the Provider is not connected to that chain. + - If rejecting for this reason, the Promise rejection error `code` **MUST** be `4901`. + +See the section [Connectivity](#connectivity) for the definitions of "connected" and "disconnected". ### Supported RPC Methods @@ -356,7 +381,9 @@ interface ProviderRpcError extends Error { | ----------- | --------------------- | ------------------------------------------------------------------------ | | 4001 | User Rejected Request | The user rejected the request. | | 4100 | Unauthorized | The requested method and/or account has not been authorized by the user. | -| 4200 | Unsupported Method | The requested method is not supported by the given Ethereum Provider. | +| 4200 | Unsupported Method | The Provider does not support the requested method. | +| 4900 | Not Connected | The Provider is not connected to any chains. | +| 4901 | Chain Not Connected | The Provider is not connected to the requested chain. | ### Events @@ -393,12 +420,14 @@ interface EthSubscription extends ProviderMessage { #### connect +See the section [Connectivity](#connectivity) for the definition of "connected". + If the Provider becomes connected, the Provider **MUST** emit the event named `connect`. -The Provider "becomes connected" when: +This includes when: -- it first connects to a chain after initialization. -- it connects to a chain after the `close` event was emitted. +- The Provider first connects to a chain after initialization. +- The Provider connects to a chain after the `disconnect` event was emitted. This event **MUST** be emitted with an object of the following form: @@ -413,9 +442,11 @@ interface ProviderConnectInfo { The `ProviderConnectInfo` object **MAY** contain any other `string` properties with values of any type. -#### close +#### disconnect + +See the section [Connectivity](#connectivity) for the definition of "disconnected". -If the Provider becomes disconnected from all chains, the Provider **MUST** emit the event named `close` with ordered values `code: number, reason: string` following the [status codes for `CloseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes). +If the Provider becomes disconnected from all chains, the Provider **MUST** emit the event named `disconnect` with value `error: ProviderRpcError`, per the interfaced defined in the [RPC Errors](#rpc-errors) section. The value of the error's `code` property **MUST** follow the [status codes for `CloseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes). #### chainChanged