{"id":"ERC-5267","name":"Retrieval of EIP-712 Domain","status":"Final","chain":"ethereum","category":{"id":"security","name":"Security & Trust","description":"Helping users verify, control, and protect their assets"},"journeyStages":[{"id":"reading","name":"Reading & Understanding","description":"Interpreting what you're being asked to do"},{"id":"approving","name":"Approving & Permissioning","description":"Granting permissions for actions"}],"uxImpact":"ERC-5267 adds eip712Domain(), a contract interface that publishes the fields and values used by its EIP-712 signing domain. Compatible applications can retrieve and validate the domain before showing a typed-data request; the interface is optional and is not a safety, trust, replay, or wallet-rendering certificate.","slug":"erc-5267","officialUrl":"https://ercs.ethereum.org/ERCS/erc-5267","sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-5267","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-5267","type":"discussion"},{"label":"OpenZeppelin EIP712 implementation with IERC5267","url":"https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol","type":"implementation"},{"label":"OpenZeppelin upgradeable EIP712 implementation","url":"https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/utils/cryptography/EIP712Upgradeable.sol","type":"implementation"},{"label":"ERC-7739 official specification","url":"https://ercs.ethereum.org/ERCS/erc-7739","type":"official-spec"}],"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","hasDetailedContent":true,"content":{"id":"ERC-5267","sources":[{"label":"ERC-5267 official specification","url":"https://ercs.ethereum.org/ERCS/erc-5267","type":"official-spec"},{"label":"OpenZeppelin EIP712 implementation with IERC5267","url":"https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/EIP712.sol","type":"implementation"},{"label":"OpenZeppelin upgradeable EIP712 implementation","url":"https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/utils/cryptography/EIP712Upgradeable.sol","type":"implementation"},{"label":"ERC-7739 official specification","url":"https://ercs.ethereum.org/ERCS/erc-7739","type":"official-spec"}],"lastReviewed":"2026-09-18","specConstraints":[{"id":"eip712-domain-interface","constraint":"A compliant contract must expose eip712Domain with the declared fields and return every specified value for reliable client decoding.","appliesTo":"account-implementation","normativity":"normative","specQuote":"Compliant contracts MUST define `eip712Domain` exactly as declared below. All specified values MUST be returned even if they are not used, to ensure proper decoding on the client side.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-5267#specification","designImplication":"Build signing and verification flows around the declared domain fields, and show an explicit unavailable or malformed-domain state when a contract does not return the expected shape."},{"id":"domain-verification-values","constraint":"The returned domain values must describe the domain separator used to verify EIP-712 signatures.","appliesTo":"wallet","normativity":"normative","specQuote":"The return values of this function MUST describe the domain separator that is used for verification of EIP-712 signatures in the contract.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-5267#specification","designImplication":"Render the retrieved domain as signing context and validate it before asking users to approve a typed-data signature; do not replace it with a display-only label."},{"id":"domain-extension-declarations","constraint":"Each declared domain extension must identify an EIP-712 extension that defines how its fields and values are obtained.","appliesTo":"wallet","normativity":"normative","specQuote":"`extensions`: A list of EIP numbers, each of which MUST refer to an EIP that extends EIP-712 with new domain fields, along with a method to obtain the value for those fields, and potentially conditions for inclusion.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-5267#specification","designImplication":"Treat extension fields as separately specified signing context, and do not silently ignore an extension identifier that the wallet cannot resolve or render."},{"id":"domain-change-awareness","constraint":"A contract's EIP-712 domain may change over its lifetime, so applications should refresh it and should not assume frequent changes are impossible.","appliesTo":"wallet","normativity":"normative","specQuote":"The return values of this function (equivalently, its EIP-712 domain) MAY change throughout the lifetime of a contract, but changes SHOULD NOT be frequent. The `chainId` field, if used, SHOULD change to mirror the [EIP-155](./eip-155.md) id of the underlying chain. Contracts MAY emit the event `EIP712DomainChanged` defined below to signal that the domain could have changed.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-5267#specification","designImplication":"Refresh cached signing context after a domain-change signal or relevant contract update, and keep chainId-aware confirmation tied to the current network."},{"id":"immutable-domain-fallback","constraint":"User-agents should support immutable contracts that cannot add the interface by using a cautious address-and-chain domain fallback.","appliesTo":"wallet","normativity":"backwards-compatibility","specQuote":"User-agents or applications that use this EIP SHOULD additionally support those contracts that due to their immutability cannot be upgraded to implement it.","specSection":"Backwards Compatibility","specUrl":"https://ercs.ethereum.org/ERCS/erc-5267#backwards-compatibility","designImplication":"Offer a clearly labeled legacy-domain path for known immutable contracts, but do not guess a domain or silently skip typed-data context when it cannot be established."},{"id":"domain-origin-validation","constraint":"Before requesting a signature, applications should generally validate that verifyingContract and chainId match the contract and current chain.","appliesTo":"wallet","normativity":"security-considerations","specQuote":"user-agents and applications should in general validate that these do match the contract and chain before requesting any user signatures for the domain.","specSection":"Security Considerations","specUrl":"https://ercs.ethereum.org/ERCS/erc-5267#security-considerations","designImplication":"Make domain mismatches blocking or unmistakably exceptional in signing UI, and explain when a contract intentionally uses a different verifyingContract or chainId."}],"lastUpdated":"2026-09-18","summary":"ERC-5267 adds eip712Domain(), a contract interface that publishes the fields and values used by its EIP-712 signing domain. Compatible applications can retrieve and validate the domain before showing a typed-data request; the interface is optional and is not a safety, trust, replay, or wallet-rendering certificate.","partialDeployment":{"body":"OpenZeppelin Contracts 5.x implements IERC5267 in its EIP712 base contracts, giving builders a concrete implementation path. Contracts may be immutable or use a different domain, and wallets or dapps may not query the interface. Detect support and retain a verified domain fallback for contracts that cannot expose it."},"designerTakeaways":["Fetch the domain from the target contract before presenting a typed-data authorization, then compare chain ID and verifying contract with the actual request.","Show which domain fields are present and treat extensions as unsupported until the application can decode them.","Keep domain retrieval separate from replay protection, contract safety, signer identity, and wallet clear-signing."],"applicability":{"whenToUse":["A product signs EIP-712 messages for permits, orders, approvals, votes, or other authorizations.","The application integrates many contracts and wants a common domain-discovery path.","The product can validate the retrieved values against its own action, chain, and contract policy."],"whenToAvoid":["The action is not an EIP-712 signature or the target contract does not verify EIP-712 domains.","The application cannot handle an unsupported extension or a domain that changes over time.","The UI would turn a retrieved domain into an unconditional trust badge."]},"prototypeFirst":[{"screen":"Domain-aware signing review","why":"The domain determines which contract, chain, and application context the signature is intended for.","covers":["Domain matches","Domain mismatch","Domain unavailable"],"include":["Present fields only","Chain and verifying contract comparison","Retrieval timestamp or block context","Raw data disclosure"]},{"screen":"Permit or order authorization","why":"Users need to distinguish the signing domain from the concrete allowance, order, or permission they are granting.","covers":["Valid domain","Stale domain","Replay or nonce failure"],"include":["Human action summary","Domain details","Nonce and deadline","Reject and refresh paths"]}],"mentalModel":[{"label":"Typed message","description":"The application asks the user to sign structured fields such as an amount, recipient, nonce, or deadline."},{"label":"Signing domain","description":"EIP-712 domain fields describe the context in which the contract verifies the typed message."},{"label":"Domain retrieval","description":"The application calls eip712Domain() to learn which optional fields and values the contract declares, when the contract implements ERC-5267."},{"label":"Independent validation","description":"The app compares the returned domain to the intended chain and contract and still applies its own nonce, expiry, authorization, and trust policy."}],"statesToDesign":[{"state":"Domain retrieved and matches","trigger":"The contract returns a supported domain whose chain and verifying contract match the action.","userNeed":"Know the signature context before approving the concrete action.","designResponse":"Show the present fields and human action together; label the result as a domain match, not a safety guarantee."},{"state":"Domain mismatch","trigger":"Retrieved chain ID or verifying contract differs from the intended target, or the domain uses a policy-disallowed value.","userNeed":"Avoid authorizing an action in another context.","designResponse":"Block signing, identify the mismatched field, and offer a refresh or safe cancellation path."},{"state":"Interface unsupported","trigger":"The target contract does not implement eip712Domain().","userNeed":"Understand why the app cannot verify a generic domain.","designResponse":"Use a separately verified domain registry or contract-specific adapter when available; otherwise show an unverified-domain warning and do not imply ERC-5267 support."},{"state":"Extension unsupported","trigger":"The returned extensions array contains an EIP the client cannot decode.","userNeed":"Know that the displayed domain is incomplete.","designResponse":"Do not construct or request the signature until the extension is understood; expose the extension number for debugging."},{"state":"Domain changed","trigger":"The contract emits EIP712DomainChanged or a fresh read returns different values.","userNeed":"Avoid signing against stale context.","designResponse":"Invalidate cached domain data, re-render the review, and explain which fields changed."}],"designDecisions":[{"question":"Should a domain match show a safety badge?","recommendation":"Use a narrow label such as Domain matches this contract and chain.","rationale":"ERC-5267 describes the verifier's domain; it does not audit code, authenticate a publisher, or make the requested authorization harmless."},{"question":"What should be cached?","recommendation":"Cache only with a contract, chain, and freshness policy, and invalidate on EIP712DomainChanged.","rationale":"The specification allows domain values to change during a contract's lifetime."},{"question":"What happens when the interface is absent?","recommendation":"Use a contract-specific verified fallback or block high-risk signing rather than guessing the domain.","rationale":"Many immutable or older contracts cannot be upgraded to expose ERC-5267."},{"question":"How do domain and message details share the hierarchy?","recommendation":"Lead with the user action, then show domain and raw fields as a reviewable context layer.","rationale":"The domain matters for authorization boundaries, but it should not hide the amount, recipient, allowance, or order terms."}],"problemsSolved":[{"problem":"Each integration hard-codes a different EIP-712 domain adapter","oldWay":"Guess name, version, chain ID, and verifying contract from token-specific code.","newWay":"Query a common eip712Domain() interface when the contract supports it.","impact":"high"},{"problem":"Users cannot tell which contract context a signature uses","oldWay":"Show a generic typed-data approval without independently checking the target domain.","newWay":"Compare the retrieved domain with the requested contract and chain before signing.","impact":"critical"},{"problem":"Domain changes are hidden behind stale app data","oldWay":"Continue showing a cached name, version, or chain after an upgrade or domain change.","newWay":"Refresh on EIP712DomainChanged or before a high-risk signature.","impact":"high"}],"uxPatterns":[{"name":"Domain Verification Layer","description":"Retrieve and compare the signing domain before rendering a typed-data confirmation.","components":["Domain field table","Contract and chain matcher","Unsupported-extension state","Refresh control"],"userFlow":["Identify target contract and chain","Call eip712Domain() when supported","Decode fields and supported extensions","Compare values with the requested domain","Render human action and domain context","Block, refresh, or continue based on policy"]},{"name":"Unverified Domain Fallback","description":"Keep signing understandable when the contract is immutable or does not expose ERC-5267.","components":["Unverified-domain warning","Verified adapter source","Raw contract and chain fields","Cancel action"],"userFlow":["Detect missing ERC-5267 support","Look up a separately verified domain only when policy allows","Show the source and freshness of that fallback","Keep concrete authorization terms visible","Require explicit consent or stop"]}],"uiComponents":[{"name":"Eip712DomainTable","description":"Shows only the fields declared by the contract, with chain and verifying-contract comparison.","kind":"list","states":["loading","matched","mismatch","unsupported","extension-unsupported","changed"],"props":["fields","expectedDomain","extensions","sourceBlock"]},{"name":"DomainTrustNotice","description":"Clarifies the boundary between a retrieved domain, application validation, and broader contract trust.","kind":"status","states":["verified-context","unverified","blocked"],"props":["verifyingContract","chainId","fallbackSource","reason"]}],"antiPatterns":[{"pattern":"Calling a domain match a security certificate","why":"The interface reports what a contract uses; it does not prove the contract or publisher is trustworthy.","instead":"Label the exact match and provide independent contract, source, and authorization review.","severity":"critical"},{"pattern":"Assuming every EIP-712 contract implements ERC-5267","why":"The interface is an optional extension and many immutable contracts predate it.","instead":"Feature-detect the call and use a verified contract-specific fallback when appropriate.","severity":"high"},{"pattern":"Showing all returned fields as active domain fields","why":"Fields not marked in the bit map are unspecified and should not be presented as part of the domain.","instead":"Decode the fields bit map and display only fields that are present.","severity":"high"},{"pattern":"Ignoring unknown domain extensions","why":"The client may show an incomplete domain and let the user sign a request it cannot interpret.","instead":"Block or explicitly mark unsupported extensions until the client can decode them.","severity":"high"},{"pattern":"Treating domain retrieval as replay protection","why":"Replay prevention still requires contract and application rules such as nonce consumption and deadlines.","instead":"Show and validate the domain alongside the actual authorization and replay policy.","severity":"critical"}],"vocabulary":[{"use":"Signing domain","avoid":"Verified app","why":"The domain describes signature context; it does not authenticate the publisher or code."},{"use":"Matches this contract and chain","avoid":"Safe to sign","why":"A context match says nothing about the requested authorization's consequences."},{"use":"Domain unavailable","avoid":"No domain","why":"The contract may still use an EIP-712 domain even when it does not expose the retrieval interface."}],"technicalNotes":"ERC-5267 requires eip712Domain() to return a bytes1 fields bitmap, name, version, chainId, verifyingContract, salt, and an extensions array. The bitmap identifies which of the five standard EIP-712 fields are present. The returned values describe the domain separator used for signature verification and may change over the contract lifetime; EIP712DomainChanged can signal a change. Contracts may use a chainId or verifyingContract different from the current chain or contract, so applications should validate those values for their policy. ERC-5267 does not define wallet rendering or application replay protection.","relatedStandards":[{"id":"EIP-712","relationship":"Defines typed structured data and the domain separator described by ERC-5267."},{"id":"ERC-2612","relationship":"A permit use case whose domain can be discovered or checked."}],"keyTakeaways":["ERC-5267 makes an EIP-712 domain queryable when a contract opts in.","Decode the fields bitmap and supported extensions before rendering the domain.","A domain match is contextual evidence, not a safety or replay guarantee.","Keep a verified fallback or a blocked state for contracts without the interface."]},"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-5267","markdown":"https://www.eipsfordesigners.com/standards/ERC-5267/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-5267/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-5267","official":"https://ercs.ethereum.org/ERCS/erc-5267","discussion":"https://ethereum-magicians.org/search?q=ERC-5267"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}