{"id":"EIP-6963","name":"Multi Injected Provider Discovery","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-6963 lets multiple injected wallets announce an EIP-1193 provider without competing for one selected connection. A dApp can show a wallet picker using the announced info.name and info.icon fields; rdns is a self-attested identifier, not proof of wallet identity or feature support.","officialUrl":"https://eips.ethereum.org/EIPS/eip-6963","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"EIP-6963","summary":"EIP-6963 lets multiple injected wallets announce an EIP-1193 provider without competing for one selected connection. A dApp can show a wallet picker using the announced info.name and info.icon fields; rdns is a self-attested identifier, not proof of wallet identity or feature support.","applicability":{"whenToUse":["Users may have more than one browser wallet installed.","Connect flows need wallet icons, names, and explicit user choice.","The product targets desktop browsers where extensions compete for injection."],"whenToAvoid":["Mobile wallet connection uses deep links or WalletConnect only.","The product binds to one wallet provider with no user choice.","Wallet discovery is handled entirely outside your UI (embedded wallet only)."]},"designerTakeaways":["Show announced providers in a picker instead of auto-connecting whichever one loaded last.","Display announced wallet icons and names for user choice; treat that metadata as self-attested and verify capabilities separately.","Remember the last chosen provider as a preference while keeping a visible switch and reconnect fallback."],"mentalModel":[{"label":"Page load","description":"The dApp dispatches eip6963:requestProvider and listens for wallet announcements instead of assuming window.ethereum."},{"label":"Wallet announcement","description":"Each wallet announces info.name, info.icon, rdns, and an EIP-1193 provider. Use the name and icon for display; treat rdns as self-attested metadata that may be unknown, invalid, or imitative."},{"label":"User choice","description":"Your connect modal lists announced providers with branding. Keep explicit selection instead of auto-connecting the first provider found."},{"label":"Selected provider","description":"Connection proceeds with the chosen provider only. Remember the last choice for reconnect but keep switch visible."},{"label":"Mobile fallback","description":"When no injected wallets exist, offer a separately integrated WalletConnect or deep-link path without treating it as part of EIP-6963."}],"problemsSolved":[{"problem":"Multiple wallets fighting for window.ethereum","oldWay":"Last wallet to load wins, user can't choose","newWay":"Each wallet announces itself, user picks","impact":"critical"},{"problem":"Users forced to disable wallets to use another","oldWay":"Disable one browser wallet extension to use another","newWay":"Announcing providers gives the dApp a way to list multiple injected providers and let the user choose","impact":"high"},{"problem":"No wallet branding in connection flow","oldWay":"Generic \"Connect Wallet\" with no context","newWay":"See wallet icons, names, choose your preference","impact":"medium"}],"uxPatterns":[{"name":"Wallet Selector Modal","description":"List of all available wallets to connect","userFlow":["User clicks Connect","App listens for EIP-6963 announcements","Shows list of detected wallets","User clicks preferred wallet","Connection proceeds with that wallet"]},{"name":"Wallet Discovery Badges","description":"Show which wallets are available before connect","userFlow":["Page loads, discovers wallets","Shows wallet icons as preview","User sees that the wallet announced a provider; feature support is checked separately.","Clicks connect with confidence"]}],"uiComponents":[{"name":"WalletList","description":"Scrollable list of available wallets","states":["loading","discovered","empty"],"props":["wallets[]","onSelect"]},{"name":"WalletOption","description":"Single wallet row with icon, name, and status","states":["idle","selected","connecting"],"props":["wallet","onClick"]},{"name":"WalletIcon","description":"Wallet brand icon with fallback","states":["loaded","fallback"],"props":["icon","name"]}],"antiPatterns":[{"pattern":"Ignoring EIP-6963 and only using window.ethereum","why":"User has no choice, random wallet selected","instead":"Listen for eip6963:announceProvider events","severity":"high"},{"pattern":"Not showing wallet icons/branding","why":"Users can't identify their wallet in the list","instead":"Display the announced info.name and info.icon; show rdns only as a technical identifier and never use it for feature detection.","severity":"medium"},{"pattern":"Auto-selecting first wallet found","why":"Removes user choice, may pick wrong wallet","instead":"Let the user explicitly choose when more than one provider is available","severity":"high"}],"specConstraints":[{"id":"provider-session-identity","constraint":"Each provider announcement includes a UUIDv4 session identifier.","appliesTo":"application","normativity":"normative","specQuote":"- **`uuid`** - a globally unique identifier the Wallet Provider that MUST be ([UUIDv4][RFC-4122] compliant) to uniquely distinguish different [EIP-1193](./eip-1193.md) provider sessions that have matching properties defined below during the lifetime of the page. The cryptographic uniqueness provided by [UUIDv4][RFC-4122] guarantees that two independent `EIP6963ProviderInfo` objects can be separately identified.","specSection":"Specification > Provider Info","specUrl":"https://eips.ethereum.org/EIPS/6963#provider-info","designImplication":"Use UUID to distinguish concurrent provider sessions and avoid collapsing wallets merely because their display metadata matches."},{"id":"provider-metadata-fallback","constraint":"rdns is self-attested and may be invalid; use graceful degradation rather than trusting it as proof of identity.","appliesTo":"application","normativity":"normative","specQuote":"- **`rdns`** - The Wallet MUST supply the `rdns` property which is intended to be a domain name from the Domain Name System in reverse syntax ordering such as `com.example.subdomain`. It's up to the Wallet to determine the domain name they wish to use, but it's generally expected the identifier will remain the same throughout the development of the Wallet. It's also worth noting that similar to a user agent string in browsers, there are times where the supplied value could be unknown, invalid, incorrect, or attempt to imitate a different Wallet. Therefore, the DApp SHOULD be able to handle these failure cases with minimal degradation to the functionality of the DApp.","specSection":"Specification > Provider Info","specUrl":"https://eips.ethereum.org/EIPS/6963#provider-info","designImplication":"Treat rdns as display/discovery metadata and provide neutral fallback labels when it fails validation or appears imitated."},{"id":"provider-svg-safety","constraint":"Provider icons must use data URIs and SVG icons MUST render through an image boundary that cannot execute untrusted JavaScript.","appliesTo":"wallet","normativity":"normative","specQuote":"The `icon` string MUST be a data URI as defined in [RFC-2397]. The image SHOULD be a square with 96x96px minimum resolution. The image format is RECOMMENDED to be either lossless or vector based such as PNG, WebP or SVG to make the image easy to render on the DApp. Since SVG images can execute Javascript, applications and libraries MUST render SVG images using the `<img>` tag to ensure no untrusted Javascript execution can occur.","specSection":"Specification > Provider Info > Images/Icons","specUrl":"https://eips.ethereum.org/EIPS/6963#images-icons","designImplication":"Render wallet-supplied icons through a safe image boundary and keep a fallback icon when metadata is missing or invalid."},{"id":"rdns-not-feature-detection","constraint":"DApps should not use self-attested rdns for feature detection.","appliesTo":"application","normativity":"normative","specQuote":"- DApps SHOULD NOT use the `rdns` value for feature detection as these are self-attested and prone to impersonation or bad incentives without an additional verification mechanism; feature-discovery and verification are both out of scope of this interface specification.","specSection":"Specification > Provider Info > RDNS","specUrl":"https://eips.ethereum.org/EIPS/6963#rdns","designImplication":"Detect capabilities through the provider interface or explicit checks, not by matching the rdns label."},{"id":"provider-rediscovery","constraint":"Wallets must announce providers and respond to request events so late listeners can rediscover them.","appliesTo":"application","normativity":"normative","specQuote":"The Wallet MUST announce the `EIP6963AnnounceProviderEvent` to the DApp via a `window.dispatchEvent()` function call. The Wallet MUST add an EventListener to catch an `EIP6963RequestProviderEvent` dispatched from the DApp. This EventListener MUST use a handler that will re-dispatch an `EIP6963AnnounceProviderEvent`. This re-announcement by the Wallet is useful for when a Wallet's initial Event announcement may have been delayed or fired before the DApp had initialized its EventListener. This allows the various Wallet Providers to react to the DApp without the need to pollute the `window.ethereum` namespace which can produce non-deterministic wallet behavior such as different wallets connecting each time.","specSection":"Specification > Window Events > Announce and Request Events","specUrl":"https://eips.ethereum.org/EIPS/6963#announce-and-request-events","designImplication":"Wallet pickers should listen during the page lifetime and support an explicit rediscovery request after initialization."},{"id":"provider-listener-lifetime","constraint":"DApps must keep the announcement listener for the lifetime of the page.","appliesTo":"application","normativity":"normative","specQuote":"The DApp MUST listen for the `EIP6963AnnounceProviderEvent` dispatched by the Wallet via a `window.addEventListener()` method and MUST NOT remove the Event Listener for the lifetime of the page so that the DApp can continue to handle Events beyond the initial page load interaction. The DApp MUST dispatch the `EIP6963RequestProviderEvent` via a `window.dispatchEvent()` function call after the `EIP6963AnnounceProviderEvent` handler has been initialized.","specSection":"Specification > Window Events > Announce and Request Events","specUrl":"https://eips.ethereum.org/EIPS/6963#announce-and-request-events","designImplication":"Do not tear down discovery listeners after the first provider; preserve the ability to add, remove, and reselect providers."},{"id":"legacy-fallback","constraint":"EIP-6963 does not require replacing window.ethereum, so legacy applications can continue to function.","appliesTo":"application","normativity":"backwards-compatibility","specQuote":"## Backwards Compatibility\n\nThis EIP doesn't require supplanting `window.ethereum`, so it doesn't directly break existing applications that cannot update to this method of Wallet discovery. However, it is RECOMMENDED DApps implement this EIP to ensure discovery of multiple Wallet Providers and SHOULD disable `window.ethereum` usage except as a fail-over when discovery fails. Similarly, Wallets SHOULD keep compatibility of `window.ethereum` to ensure backwards compatibility for DApps that have not implemented this EIP. In order to prevent the previous issues of namespace collisions, it's also RECOMMENDED that wallets inject their provider object under a wallet specific namespace then proxy the object into the `window.ethereum` namespace.","specSection":"Backwards Compatibility","specUrl":"https://eips.ethereum.org/EIPS/6963#backwards-compatibility","designImplication":"Design a compatibility fallback for legacy provider discovery and make the selected provider explicit when multiple paths exist."},{"id":"provider-object-integrity","constraint":"Wallet providers can modify page and provider objects by design, so applications must treat them as highly trusted inputs.","appliesTo":"application","normativity":"security-considerations","specQuote":"### Prototype Pollution of Wallet Provider objects\n\nBrowser extensions, and therefore Wallet extensions, are able to modify the contents of the page and the Provider object by design. The provider objects of various Wallets are considered a highly trusted interface to communicate transaction data. In order to prevent the page or various other extensions from modifying the interaction between the DApp and the Wallet in an unexpected way, the best practice is to \"freeze\" the provider discovery object by utilizing `object.freeze()` on the  `EIP1193Provider` object before the wallet dispatches it in the `eip6963:announceProvider` Event. However, there are difficulties that can occur around web compatibility where pages need to monkey patch the object. In scenarios like this there's a tradeoff that needs to be made between security and web compatibility that Wallet implementers are expected to consider.","specSection":"Security Considerations > Prototype Pollution of Wallet Provider objects","specUrl":"https://eips.ethereum.org/EIPS/6963#prototype-pollution-of-wallet-provider-objects","designImplication":"Keep provider objects isolated from untrusted application state, avoid unsafe mutation assumptions, and provide a clear account/network source in the UI."},{"id":"provider-imitation","constraint":"DApps should actively detect provider-property or function tampering and wallet imitation.","appliesTo":"application","normativity":"security-considerations","specQuote":"### Wallet Imitation and Manipulation\n\nSimilarly so, DApps are expected to actively detect for misbehavior of properties or functions being modified in order to tamper with or modify other wallets. One way this can be easily achieved is to look for when the `uuid` property within two `EIP6963ProviderInfo` objects match. DApps and DApp discovery libraries are expected to consider other potential methods that the `EIP6963ProviderInfo` objects are being tampered with and consider additional mitigation techniques to prevent this as well in order to protect the user.","specSection":"Security Considerations > Wallet Imitation and Manipulation","specUrl":"https://eips.ethereum.org/EIPS/6963#wallet-imitation-and-manipulation","designImplication":"Do not present a wallet name or icon as a security guarantee; provide a mismatch/verification warning when provider behavior conflicts with expected capabilities."},{"id":"wallet-fingerprinting","constraint":"Provider discovery should return promptly after prompting/error rather than waiting for user acceptance, reducing fingerprinting.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"### Prevent Wallet Fingerprinting\n\nOne advantage to the concurrency Event loop utilized by this design is that it operates in a manner where either the DApp or the Wallet can initiate the flow to announce a provider. For this reason, Wallet implementers can now consider whether or not they wish to announce themselves to all pages or attempt alternative means in order to reduce the ability for a user to be fingerprinted by the injection of the `window.ethereum` object. Some examples, of alternative flows to consider would be to wait to inject the provider object until the DApp has announced the `eip6963:requestProvider`. At that point, the wallet can initiate a UI consent flow to ask the user if they would like to share their wallet address. This allows for the Wallet to enable the option of a \"private connect\" feature. However, if this approach is taken, Wallets must also consider how they intend to support backwards compatibility with a DApp that does not support this EIP.","specSection":"Security Considerations > Prevent Wallet Fingerprinting","specUrl":"https://eips.ethereum.org/EIPS/6963#prevent-wallet-fingerprinting","designImplication":"Separate “prompt shown”, “rejected”, and “connected” states while avoiding timing behavior that reveals a user’s wallet inventory."},{"id":"provider-extra-properties","constraint":"The EIP6963ProviderInfo object MAY include extra extensible properties, and a DApp SHOULD ignore properties it does not recognize.","appliesTo":"application","normativity":"normative","specQuote":"Each Wallet Provider will be announced with the following interface `EIP6963ProviderInfo`. The values in the `EIP6963ProviderInfo` MUST be included within the `EIP6963ProviderInfo` object. The `EIP6963ProviderInfo` MAY also include extra extensible properties within the object. If a DApp does not recognize the additional properties, it SHOULD ignore them.","specSection":"Specification > Provider Info","specUrl":"https://eips.ethereum.org/EIPS/eip-6963#provider-info","designImplication":"Keep wallet discovery and provider cards forward-compatible: unknown metadata should be ignored without breaking selection or rendering known fields."},{"id":"provider-selection-persistence","constraint":"A DApp MAY persist provider details to let a user select a different wallet later, or MAY re-initiate discovery when the saved choice is not used.","appliesTo":"application","normativity":"normative","specQuote":"The DApp MAY elect to persist various `EIP6963ProviderDetail` objects contained in the  announcement events sent by multiple wallets. Thus, if the user wishes to utilize a different Wallet over time, the user can express this within the DApp's interface and the DApp can immediately elect to send transactions to that new Wallet. Otherwise, the DApp MAY re-initiate the wallet discovery flow via dispatching a new `EIP6963RequestProviderEvent`, potentially discovering a different set of wallets.","specSection":"Specification > Window Events > Announce and Request Events","specUrl":"https://eips.ethereum.org/EIPS/eip-6963#announce-and-request-events","designImplication":"Let users see and change the selected wallet explicitly, and provide a rediscovery path when stored provider details are stale or unavailable."}],"keyTakeaways":["EIP-6963 = multiple wallet discovery","Show a selector when multiple providers are announced; keep an explicit choice and reconnect path.","Display announced icons and names clearly without treating them as identity proof.","Integrate a separate WalletConnect or deep-link fallback when the product needs mobile support.","Handle no-wallets-detected gracefully"],"technicalNotes":"EIP-6963 uses DOM events: the dApp listens for eip6963:announceProvider and dispatches eip6963:requestProvider. Each detail includes info.name, info.icon, self-attested rdns, and an EIP-1193 provider. rdns can be unknown, invalid, or imitative; feature discovery and verification are outside this interface.","lastUpdated":"2026-09-18","sources":[{"label":"EIP-6963 official specification","url":"https://eips.ethereum.org/EIPS/eip-6963","type":"official-spec"}],"lastReviewed":"2026-09-18"},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/eip-6963","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=EIP-6963","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/EIP-6963","markdown":"https://www.eipsfordesigners.com/standards/EIP-6963/content.md","agent":"https://www.eipsfordesigners.com/standards/EIP-6963/agent.md","api":"https://www.eipsfordesigners.com/api/standards/EIP-6963","official":"https://eips.ethereum.org/EIPS/eip-6963","discussion":"https://ethereum-magicians.org/search?q=EIP-6963"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}