{"id":"EIP-1193","name":"Ethereum Provider JavaScript API","status":"Final","chain":"both","category":{"id":"onboarding","name":"Onboarding & Access","description":"Getting users into web3 without friction"},"journeyStages":[{"id":"discovery","name":"Discovery & Connection","description":"Finding and connecting wallet to dApp"}],"uxImpact":"EIP-1193 defines a transport-agnostic Provider API for dApps: request methods, provider events, and standard error shapes. It gives applications a common wallet communication surface, but it does not require window.ethereum, make every RPC method available, or guarantee that every wallet supports every dApp feature.","officialUrl":"https://eips.ethereum.org/EIPS/eip-1193","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"EIP-1193","specConstraints":[{"id":"eip-1193-provider-connectivity","constraint":"A provider is connected only when it can service requests to at least one chain; network failure makes it disconnected.","appliesTo":"wallet","normativity":"normative","specQuote":"To service an RPC request, the Provider must successfully submit the request to the remote location, and receive a response.","specSection":"Specification — Connectivity","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#connectivity","designImplication":"Represent provider connectivity as a live state and distinguish no-chain connectivity from a request-specific failure. Do not leave a connected-looking wallet action enabled after the provider can no longer reach a chain."},{"id":"eip-1193-request-outcome","constraint":"Each RPC request must resolve with the method result or reject with an error.","appliesTo":"wallet","normativity":"normative","specQuote":"RPC requests **MUST** be handled such that the returned Promise either resolves with a value per the requested RPC method's specification, or rejects with an error.","specSection":"Specification — API — request","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#request","designImplication":"Give every request a clear pending, success, and error state. Keep a wallet action from appearing successful when the provider returned no method-level result."},{"id":"eip-1193-provider-errors","constraint":"Rejected provider requests must expose a ProviderRpcError so applications can give a specific recovery path.","appliesTo":"wallet","normativity":"normative","specQuote":"If the returned Promise rejects, it **MUST** reject with a `ProviderRpcError` as specified in the [RPC Errors](#rpc-errors) section below.","specSection":"Specification — API — request","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#request","designImplication":"Map provider error codes to human recovery copy and preserve the user's input where retry is safe. Avoid collapsing authorization, unsupported-method, and connectivity errors into one generic failure."},{"id":"eip-1193-disconnected-error-code","constraint":"A request rejected because the provider is disconnected from all chains uses error code 4900.","appliesTo":"wallet","normativity":"normative","specQuote":"If rejecting for this reason, the Promise rejection error `code` **MUST** be `4900`.","specSection":"Specification — API — request","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#request","designImplication":"Show a disconnected recovery state that is distinct from a rejected signature or a chain-specific outage."},{"id":"eip-1193-chain-disconnected-error-code","constraint":"A request for an unavailable chain uses error code 4901 when the provider remains connected to another chain.","appliesTo":"wallet","normativity":"normative","specQuote":"If rejecting for this reason, the Promise rejection error `code` **MUST** be `4901`.","specSection":"Specification — API — request","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#request","designImplication":"Tell users which requested chain is unavailable and offer a supported network switch or a safe cancel path without implying the whole wallet is offline."},{"id":"eip-1193-readable-errors","constraint":"Provider errors expose a human-readable message and an integer error code.","appliesTo":"wallet","normativity":"normative","specQuote":"- `message`\n  - **MUST** be a human-readable string\n  - **SHOULD** adhere to the specifications in the [Error Standards](#error-standards) section below\n- `code`\n  - **MUST** be an integer number\n  - **SHOULD** adhere to the specifications in the [Error Standards](#error-standards) section below","specSection":"Specification — Supported RPC Methods — RPC Errors","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#rpc-errors","designImplication":"Use the provider error as structured input for a user-facing explanation, while keeping technical data available for support and diagnostics."},{"id":"eip-1193-subscription-messages","constraint":"A provider that supports Ethereum RPC subscriptions must emit subscription notifications through the message event.","appliesTo":"application","normativity":"normative","specQuote":"If the Provider supports Ethereum RPC subscriptions, e.g. [`eth_subscribe`](https://geth.ethereum.org/docs/rpc/pubsub), the Provider **MUST** emit the `message` event when it receives a subscription notification.","specSection":"Specification — Events — message — Subscriptions","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#subscriptions","designImplication":"Treat subscription-driven activity as an event stream and show a recoverable stale or disconnected state when notifications stop."},{"id":"eip-1193-connect-event","constraint":"The provider must emit connect when it becomes able to service a chain.","appliesTo":"application","normativity":"normative","specQuote":"If the Provider becomes connected, the Provider **MUST** emit the event named `connect`.","specSection":"Specification — Events — connect","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#connect","designImplication":"Use connect to move the interface from unavailable or reconnecting to actionable, while still refreshing chain and account state before enabling a write."},{"id":"eip-1193-chain-id-format","constraint":"The connect event's chainId is the connected chain's integer ID encoded as a hexadecimal string.","appliesTo":"application","normativity":"normative","specQuote":"`chainId` **MUST** specify the integer ID of the connected chain as a hexadecimal string, per the [`eth_chainId`](./eip-695.md) Ethereum RPC method.","specSection":"Specification — Events — connect","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#connect","designImplication":"Display and compare chain identity using the provider's canonical hexadecimal value; do not infer a network from wallet branding or a stale chain label."},{"id":"eip-1193-disconnect-event","constraint":"When disconnected from all chains, the provider must emit disconnect with a ProviderRpcError.","appliesTo":"application","normativity":"normative","specQuote":"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.","specSection":"Specification — Events — disconnect","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#disconnect","designImplication":"Move pending wallet actions into a disconnected state and explain whether retrying after reconnection is safe."},{"id":"eip-1193-chain-changed-event","constraint":"A provider must emit chainChanged with the new chain ID whenever its connected chain changes.","appliesTo":"application","normativity":"normative","specQuote":"If the chain the Provider is connected to changes, the Provider **MUST** emit the event named `chainChanged` with value `chainId: string`, specifying the integer ID of the new chain as a hexadecimal string, per the [`eth_chainId`](./eip-695.md) Ethereum RPC method.","specSection":"Specification — Events — chainChanged","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#chainchanged","designImplication":"Refresh balances, permissions, previews, and network-sensitive copy on chain change. Never let a confirmation panel retain the old chain context."},{"id":"eip-1193-accounts-changed-event","constraint":"A provider must emit accountsChanged with the current account list whenever the accounts available to it change.","appliesTo":"application","normativity":"normative","specQuote":"If the accounts available to the Provider change, the Provider **MUST** emit the event named `accountsChanged` with value `accounts: string[]`, containing the account addresses per the `eth_accounts` Ethereum RPC method.","specSection":"Specification — Events — accountsChanged","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#accountschanged","designImplication":"Invalidate account-scoped actions and refresh ownership, balances, and permissions when the active account list changes."},{"id":"eip-1193-provider-security-boundary","constraint":"The provider is a message transport, not the private-key or account-security boundary.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"It is _not_ responsible for private key or account management; it merely processes RPC messages and emits events.","specSection":"Security Considerations","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#security-considerations","designImplication":"Keep signing authority and privacy decisions in the wallet layer. A provider-connected app should not imply that the provider itself verifies the safety of a transaction or protects keys."},{"id":"eip-1193-adversarial-provider","constraint":"A provider exposed to an untrusted consumer must not contain private user data, and wallet/client boundaries must isolate and validate its requests.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"The Provider can be thought of as an extension of the Wallet, exposed in an untrusted environment, under the control of some third party (e.g. a website).\n\n### Handling Adversarial Behavior\n\nSince it is a JavaScript object, consumers can generally perform arbitrary operations on the Provider, and all its properties can be read or overwritten.\nTherefore, it is best to treat the Provider object as though it is controlled by an adversary.\nIt is paramount that the Provider implementer protects the user, Wallet, and Client by ensuring that:\n\n- The Provider does not contain any private user data.\n- The Provider and Wallet programs are isolated from each other.\n- The Wallet and/or Client rate-limit requests from the Provider.\n- The Wallet and/or Client validate all data sent from the Provider.","specSection":"Security Considerations — Handling Adversarial Behavior","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#handling-adversarial-behavior","designImplication":"Treat the provider object as adversarial input. Keep sensitive data out of the exposed object and validate, isolate, and rate-limit requests before they reach wallet or client authority."},{"id":"eip-1193-accurate-chain-state","constraint":"The provider must accurately reflect the client's configured chain and emit chainChanged whenever that value changes.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"Since all Ethereum operations are directed at a particular chain, it's important that the Provider accurately reflects the Client's configured chain, per the `eth_chainId` Ethereum RPC method (see [EIP-695](./eip-695.md)).\n\nThis includes ensuring that `eth_chainId` has the correct return value, and that the `chainChanged` event is emitted whenever that value changes.","specSection":"Security Considerations — Chain Changes","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#chain-changes","designImplication":"Treat chain identity as a safety-critical input. Refresh network-sensitive previews and block signing when the provider's reported chain is stale or inconsistent."},{"id":"eip-1193-account-exposure-opt-in","constraint":"Accounts should not be exposed by default; access should be explicitly requested through a permission-capable method.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"In order to protect user privacy, the authors recommend not exposing any accounts by default.","specSection":"Security Considerations — User Account Exposure and Account Changes","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#user-account-exposure-and-account-changes","designImplication":"Make account disclosure an explicit user action and show the resulting scope. Do not treat a connected provider as permission to reveal every account."},{"id":"eip-1193-legacy-api-compatibility","constraint":"The finalized provider API is a strict superset of the legacy API, but providers implementing only the current specification are not compatible with legacy-targeting applications.","appliesTo":"application","normativity":"backwards-compatibility","specQuote":"The current API is designed to be a strict superset of the legacy version, and this specification is in that sense fully backwards compatible.","specSection":"Backwards Compatibility","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#backwards-compatibility","designImplication":"Keep a deliberate compatibility or fallback path for legacy integrations; do not assume API-level compatibility guarantees that the application-side migration does not provide."},{"id":"eip-1193-connection-rejection-recommendation","constraint":"A provider SHOULD reject requests when it is disconnected from all chains or unavailable on the requested chain while connected elsewhere, using the corresponding error code.","appliesTo":"wallet","normativity":"normative","specQuote":"The returned Promise **SHOULD** reject if any of the following conditions are met:\n\n- The Provider is disconnected.\n  - If rejecting for this reason, the Promise rejection error `code` **MUST** be `4900`.\n- The RPC request is directed at a specific chain, and the Provider is not connected to that chain, but is connected to at least one other chain.\n  - If rejecting for this reason, the Promise rejection error `code` **MUST** be `4901`.","specSection":"Specification — API — request","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#request","designImplication":"Keep requests visibly pending or failed when the provider cannot reach the target chain, and give users a targeted recovery state without treating all connection failures as wallet-wide outages."},{"id":"eip-1193-method-flexibility","constraint":"Providers MAY support the RPC methods needed for their purpose, whether standardized or otherwise.","appliesTo":"wallet","normativity":"normative","specQuote":"Providers **MAY** support whatever RPC methods required to fulfill their purpose, standardized or otherwise.","specSection":"Specification — Supported RPC Methods","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#supported-rpc-methods","designImplication":"Feature-detect each requested method and provide an unsupported-capability state; a connected provider does not imply that every dapp feature is available."},{"id":"eip-1193-unsupported-method-rejection","constraint":"When a finalized EIP RPC method is unsupported, the provider SHOULD reject it with error 4200 or the method's specified error.","appliesTo":"wallet","normativity":"normative","specQuote":"If an RPC method defined in a finalized EIP is not supported, it **SHOULD** be rejected with a `4200` error per the [Provider Errors](#provider-errors) section below, or an appropriate error per the RPC method's specification.","specSection":"Specification — Supported RPC Methods","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#supported-rpc-methods","designImplication":"Translate unsupported-method responses into a clear capability explanation and a fallback or stop path, rather than presenting a generic transaction failure."},{"id":"eip-1193-error-standards","constraint":"ProviderRpcError messages and codes SHOULD follow the Error Standards conventions, and error data SHOULD contain other useful information when available.","appliesTo":"wallet","normativity":"normative","specQuote":"- `message`\n  - **MUST** be a human-readable string\n  - **SHOULD** adhere to the specifications in the [Error Standards](#error-standards) section below\n- `code`\n  - **MUST** be an integer number\n  - **SHOULD** adhere to the specifications in the [Error Standards](#error-standards) section below\n- `data`\n  - **SHOULD** contain any other useful information about the error","specSection":"Specification — Supported RPC Methods — RPC Errors","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#rpc-errors","designImplication":"Use standard error semantics for recovery copy and preserve useful data for diagnostics, without making raw provider details the primary user-facing message."},{"id":"eip-1193-error-priority","constraint":"ProviderRpcError codes and messages SHOULD follow the listed conventions in priority order.","appliesTo":"wallet","normativity":"normative","specQuote":"`ProviderRpcError` codes and messages **SHOULD** follow these conventions, in order of priority:\n\n1. The errors in the [Provider Errors](#provider-errors) section below\n\n2. Any errors mandated by the erroring RPC method's specification\n\n3. The [`CloseEvent` status codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes)","specSection":"Specification — Supported RPC Methods — RPC Errors — Error Standards","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#error-standards","designImplication":"Resolve error copy in the specified order: Provider Errors first, then errors mandated by the failing RPC method, then CloseEvent status codes as the final convention."},{"id":"eip-1193-account-access-request","constraint":"Providers SHOULD support explicit RPC methods for requesting account access instead of exposing accounts by default.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"Instead, Providers should support RPC methods for explicitly requesting account access, such as `eth_requestAccounts` (see [EIP-1102](./eip-1102.md)) or `wallet_requestPermissions` (see [EIP-2255](./eip-2255.md)).","specSection":"Security Considerations — User Account Exposure and Account Changes","specUrl":"https://eips.ethereum.org/EIPS/eip-1193#user-account-exposure-and-account-changes","designImplication":"Make account access an explicit request with a visible permission boundary; do not treat provider availability as consent to reveal an account."}],"summary":"EIP-1193 defines a transport-agnostic Provider API for dApps: request methods, provider events, and standard error shapes. It gives applications a common wallet communication surface, but it does not require window.ethereum, make every RPC method available, or guarantee that every wallet supports every dApp feature.","applicability":{"whenToUse":["Apps need a transport-agnostic provider.request() and standard provider events.","Connection state must react to accountsChanged, chainChanged, disconnect, or message events.","The product needs feature-detected wallet methods with clear ProviderRpcError recovery."],"whenToAvoid":["Mobile-only flows use WalletConnect with no window.ethereum.","Embedded wallets hide provider choice entirely.","You trigger eth_requestAccounts on page load without user action."]},"designerTakeaways":["Use provider.request() and standard events for the common connection and status surface.","Pair EIP-1193 with EIP-6963 for injected-wallet discovery; keep window.ethereum as a legacy or fallback path.","Feature-detect methods and capabilities, and turn ProviderRpcError codes into human recovery copy."],"designDecisions":[{"question":"When do you call eth_requestAccounts?","recommendation":"Trigger on explicit Connect Wallet click, not on page load.","rationale":"Surprise wallet popups erode trust and increase rejection rates."},{"question":"How do you map provider errors?","recommendation":"Map 4001, 4100, 4900, and 4901 to consistent, human-readable messages.","rationale":"Raw error codes are meaningless to designers and users alike."},{"question":"What happens on chain change?","recommendation":"Pause actions and prompt reload or auto-refresh contract-dependent state.","rationale":"Stale chain state causes wrong balances and failed transactions."},{"question":"How is the connected account shown?","recommendation":"Truncated address, network name, and a clear disconnect control.","rationale":"Users must always know which identity and chain the app is using."}],"statesToDesign":[{"state":"No provider","trigger":"No injected provider is detected; another provider path may still be available.","userNeed":"Install or choose a wallet path.","designResponse":"Explain the available injected, embedded, mobile, or external connection paths and their support limits."},{"state":"Disconnected","trigger":"User has not approved eth_requestAccounts.","userNeed":"Start the session safely.","designResponse":"Primary Connect Wallet CTA; no gated content that requires guessing."},{"state":"Connected","trigger":"Accounts array non-empty.","userNeed":"See active address and network.","designResponse":"Account chip with network badge and disconnect."},{"state":"User rejected (4001)","trigger":"User closes wallet prompt without approving.","userNeed":"Retry without feeling blocked.","designResponse":"Neutral copy: \"Connection cancelled\" with retry button."},{"state":"Wrong network","trigger":"chainId does not match app requirement.","userNeed":"Switch network or understand mismatch.","designResponse":"Block actions; offer Switch network when wallet supports it."}],"problemsSolved":[{"problem":"No standard way for dApps to communicate with wallets","oldWay":"Each wallet invented their own API, dApps wrote custom code for each","newWay":"A common provider.request() API and event model work across conforming providers","impact":"critical"},{"problem":"Users couldn't use their preferred wallet","oldWay":"A dApp supports one provider integration and excludes other compatible wallets","newWay":"A dApp can integrate the provider API once, while still feature-detecting wallet methods and capabilities","impact":"high"},{"problem":"Inconsistent connection experience","oldWay":"Different buttons, flows, and errors for each wallet","newWay":"A product can reuse a provider request and event model while adapting to each provider's supported methods and errors","impact":"high"}],"uxPatterns":[{"name":"Connect Wallet Button","description":"The ubiquitous entry point to web3","userFlow":["User sees Connect Wallet button","Click triggers eth_requestAccounts","Wallet popup asks for permission","User approves connection","dApp receives account address"]},{"name":"Connected State","description":"Show connected wallet with truncated address","userFlow":["User connected successfully","Show truncated address","Display network name","Provide disconnect option"]}],"uiComponents":[{"name":"ConnectWalletButton","description":"Primary CTA for initiating wallet connection","states":["idle","connecting","connected","error"],"props":["onConnect","onDisconnect"]},{"name":"AddressPill","description":"Truncated address with optional ENS","states":["address-only","with-ens","loading"],"props":["address","ensName","onClick"]},{"name":"NetworkBadge","description":"Shows current connected network","states":["mainnet","testnet","unknown","wrong-network"],"props":["chainId","expectedChainId"]}],"antiPatterns":[{"pattern":"Auto-connecting without user action","why":"Privacy violation, users didn't consent to share address","instead":"Always require explicit \"Connect\" click first","severity":"critical"},{"pattern":"Not handling account/chain changes","why":"User switches account in wallet, dApp still shows old one","instead":"Listen to accountsChanged and chainChanged events","severity":"high"},{"pattern":"Showing full 42-character addresses","why":"Unreadable, wastes space, looks intimidating","instead":"Truncate: 0x7a3...f9c2 or show ENS name","severity":"medium"}],"keyTakeaways":["EIP-1193 standardizes provider.request() and provider events for wallet communication.","Never auto-connect without user action.","Listen for account and chain change events.","Truncate addresses or show ENS names.","Handle connection errors gracefully."],"technicalNotes":"EIP-1193 defines a Provider with a transport- and protocol-agnostic request() method plus connect, disconnect, chainChanged, accountsChanged, and message events. window.ethereum is a common injection convention outside the specification. Providers can expose different RPC methods and authorization behavior, so feature-detect the requested capability and handle ProviderRpcError codes.","lastUpdated":"2026-09-18","sources":[{"label":"EIP-1193 official specification","url":"https://eips.ethereum.org/EIPS/eip-1193","type":"official-spec"}],"lastReviewed":"2026-09-18"},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/eip-1193","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=EIP-1193","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/EIP-1193","markdown":"https://www.eipsfordesigners.com/standards/EIP-1193/content.md","agent":"https://www.eipsfordesigners.com/standards/EIP-1193/agent.md","api":"https://www.eipsfordesigners.com/api/standards/EIP-1193","official":"https://eips.ethereum.org/EIPS/eip-1193","discussion":"https://ethereum-magicians.org/search?q=EIP-1193"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}