diff --git a/EIPS/eip-1193.md b/EIPS/eip-1193.md index 85cdb83e4871ed..abd5a3f7fd1f8e 100644 --- a/EIPS/eip-1193.md +++ b/EIPS/eip-1193.md @@ -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 @@ -29,13 +29,13 @@ Makes an Ethereum RPC method call. ```typescript type RequestParams = Array | { [key: string]: any }; -ethereum.request(method: string, params?: RequestParams): Promise; +Provider.request(method: string, params?: RequestParams): Promise; ``` 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)); @@ -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. @@ -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): unknown; +Provider.send(...args: Array): unknown; ``` ### Events @@ -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. @@ -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). @@ -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. @@ -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) => void): ethereum; +Provider.on('accountsChanged', listener: (accounts: Array) => void): Provider; ``` The event emits with `accounts`, an array of account addresses, per the `eth_accounts` Ethereum RPC method. @@ -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 @@ -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 @@ -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 @@ -301,7 +317,7 @@ The Provider **MAY** expose methods and properties not specified in this documen ```typescript type RequestParams = Array | { [key: string]: any }; -ethereum.request(method: string, params?: RequestParams): Promise; +Provider.request(method: string, params?: RequestParams): Promise; ``` The `request` method is intended as a transport- and protocol-agnostic wrapper function for Remote Procedure Calls (RPCs).