← Protocols
EIP-1193 — Ethereum Provider JavaScript API
Standard / EIP·EVM

EIP-1193 — Ethereum Provider JavaScript API

01Description

Final Interface EIP defining the standard JavaScript Ethereum provider exposed to dapps as `window.ethereum`. Specifies a single `request({ method, params })` RPC entrypoint plus five lifecycle events (`connect`, `disconnect`, `chainChanged`, `accountsChanged`, `message`) so wallets and dapps interoperate without bespoke globals.

02Best for
  • 01any dapp that connects to a browser/extension/in-app wallet
  • 02implementing a wallet that injects a provider
  • 03wagmi / viem / ethers BrowserProvider integrations
  • 04EIP-6963 multi-provider discovery
  • 05RPC method routing in wallet middleware
03Install
  • pnpm add viem
  • pnpm add wagmi
  • pnpm add ethers
05Prompt snippet
Talk to wallets through the EIP-1193 `EIP1193Provider` interface — `provider.request({ method: 'eth_requestAccounts' })`, `eth_chainId`, `eth_sendTransaction`, `wallet_switchEthereumChain`, `personal_sign`, `eth_signTypedData_v4` — and never assume a global `window.ethereum`. Wire the five events: `connect ({ chainId })`, `disconnect (ProviderRpcError)`, `chainChanged (chainId: hex string)`, `accountsChanged (string[])`, `message (ProviderMessage)`. Always re-read `eth_chainId` on `chainChanged` and treat an empty `accountsChanged` array as a disconnect. Use viem's `custom(window.ethereum)` transport or wagmi's injected connector — both implement EIP-1193 + EIP-6963 discovery for you. Errors come back as `ProviderRpcError` with EIP-1193 codes (`4001` user rejected, `4100` unauthorized, `4200` unsupported method, `4900` disconnected, `4901` chain disconnected).
06Gotchas
  • Provider lifecycle: register `chainChanged` and `accountsChanged` listeners exactly once per provider instance and tear them down on unmount — re-registering on every render leaks listeners and double-fires state updates.
  • `chainId` events deliver hex strings (`'0x1'`) while many dapp libraries store decimals — always normalise via `parseInt(chainId, 16)` and never compare hex to decimal.
  • An empty array from `accountsChanged` MUST be treated as a logout; it is not a transient empty state, and continuing to sign with the old account leaks UX bugs and wallet errors.
  • Do not bind to `window.ethereum` directly anymore — multiple wallets fight for the global. Use EIP-6963 (`eip6963:announceProvider`) to enumerate `EIP1193Provider`s and let the user pick.
  • `request` is the only spec'd method; legacy `send` / `sendAsync` are removed. Do not call them, and do not rely on `provider.enable()` — issue `eth_requestAccounts` instead.
07Alternatives