{"id":"ERC-7409","name":"Public NFT Emote Repository V2","status":"Final","chain":"both","category":{"id":"social","name":"Social & Messaging","description":"Communication and reactions"},"journeyStages":[{"id":"specialized","name":"Specialized Interactions","description":"Physical items, AI, social, gaming"}],"uxImpact":"ERC-7409 is the Final successor to ERC-6381 for public NFT emotes, using string-based emoji encoding that supports multi-codepoint and skin-tone variants. Existing ERC-6381 collections may remain usable; new integrations should prefer ERC-7409 and show wallet activity separately from unique-human sentiment.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-7409","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"ERC-7409","sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-7409","type":"official-spec"}],"lastReviewed":"2026-09-18","specConstraints":[{"id":"emote-event-state","constraint":"The Emoted event must be emitted only when an emote's state changes.","appliesTo":"application","normativity":"normative","specQuote":"* @dev The event MUST only be emitted if the state of the emote is changed.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#specification","designImplication":"Treat Emoted as a state-change signal, not a heartbeat; update active reaction state from it without inflating counts on duplicate no-op requests."},{"id":"bulk-array-lengths","constraint":"Bulk emote operations must revert when collections, tokenIds, emojis, and states arrays have different lengths.","appliesTo":"application","normativity":"normative","specQuote":"* @dev MUST revert if the lengths of the `collections`, `tokenIds`, `emojis` and `states` arrays are not equal.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#specification","designImplication":"Validate bulk reaction selections before signing or submitting, and keep the batch as one failed operation when its parallel arrays do not align."},{"id":"presigned-deadline","constraint":"Presigned emote operations must reject signatures after their deadline.","appliesTo":"application","normativity":"normative","specQuote":"* @dev MUST revert if the `deadline` has passed.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#specification","designImplication":"Show the validity deadline before a user signs, refresh stale messages, and represent an expired presigned reaction as unavailable rather than retrying it silently."},{"id":"recovered-signer","constraint":"A presigned emote must reject a signature whose recovered signer is the zero address.","appliesTo":"account-implementation","normativity":"normative","specQuote":"* @dev MUST revert if the recovered address is the zero address.","specSection":"Specification","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#specification","designImplication":"Keep invalid signature recovery visible as a failed authorization and never show a reaction as user-consented when signer recovery returned zero."},{"id":"erc721-compatibility","constraint":"The Emote repository remains compatible with ERC-721 tooling and infrastructure.","appliesTo":"application","normativity":"backwards-compatibility","specQuote":"The Emote repository standard is fully compatible with [ERC-721](./eip-721.md) and with the robust tooling available for implementations of ERC-721 as well as with the existing ERC-721 infrastructure.","specSection":"Backwards Compatibility","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#backwards-compatibility","designImplication":"Attach reactions to ordinary NFT collection and token identity flows while keeping the repository's wallet-based activity separate from NFT ownership."},{"id":"presigned-replay-domain","constraint":"The presigned message domain is unique to the repository contract on its deployed chain, limiting cross-chain replay.","appliesTo":"account-implementation","normativity":"security-considerations","specQuote":"The `DOMAIN_SEPARATOR` used in the message to be signed is unique to the repository smart contract of the chain it is deployed on.","specSection":"Security Considerations","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#security-considerations","designImplication":"Bind signing previews and verification to the repository contract and chain, and show a network mismatch instead of treating a valid signature as portable everywhere."},{"id":"presigned-replay-deadline","constraint":"Services using presigned messages should choose reasonably short deadlines to limit message reuse.","appliesTo":"application","normativity":"security-considerations","specQuote":"We suggest that the services using the repository in conjunction with presigned messages use deadlines that invalidate presigned messages after a reasonably short period of time.","specSection":"Security Considerations","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#security-considerations","designImplication":"Make the message expiry visible and keep deadlines short enough for the service's risk model, especially where a reaction can be re-applied after it is revoked."},{"id":"presigned-replay-rejection","constraint":"An Emote repository SHOULD revert a presigned reaction when its replay-protection domain does not match the deployed chain.","appliesTo":"account-implementation","normativity":"security-considerations","specQuote":"This means that the signature is invalid on any other chain and the Emote repositories deployed on them should revert the operation if a replay attack is attempted.","specSection":"Security Considerations","specUrl":"https://ercs.ethereum.org/ERCS/erc-7409#security-considerations","designImplication":"Show a network-mismatch failure for a replayed presigned reaction and do not offer a retry that silently changes the signing domain."}],"lastUpdated":"2026-09-18","summary":"ERC-7409 is the Final successor to ERC-6381 for public NFT emotes, using string-based emoji encoding that supports multi-codepoint and skin-tone variants. Existing ERC-6381 collections may remain usable; new integrations should prefer ERC-7409 and show wallet activity separately from unique-human sentiment.","designerTakeaways":["Attach a reaction bar to an NFT when the target collection exposes the ERC-7409 repository.","Support multi-codepoint strings and skin-tone variants with an accessible picker and fallback rendering.","Prefer ERC-7409 for new integrations and keep any ERC-6381 compatibility path visibly labeled."],"applicability":{"whenToUse":["A product needs public on-chain reaction events and current active counts.","The target collection or repository implements ERC-7409 string-based emotes.","The UI can distinguish wallet activity, event history, and any product-level rollup."],"whenToAvoid":["The target collection only exposes ERC-6381 and no compatibility or migration plan exists.","The product needs irreversible reactions or unique-human sentiment metrics.","The UI cannot render or safely fall back for multi-codepoint emoji strings."]},"prototypeFirst":[{"screen":"NFT reaction bar","why":"Primary social interaction surface.","covers":["No reactions","Popular reactions","Your reaction"],"include":["Quick emoji row","Add reaction","Count badges"]},{"screen":"Full emoji picker","why":"7409 value is full Unicode including skin tones.","covers":["Picker open","Skin tone select"],"include":["Category tabs","Skin tone long-press","Search"]},{"screen":"Reaction list expand","why":"See who reacted with what.","covers":["Reaction aggregations"],"include":["Emoji group headers","User list per emoji","Remove your reaction"]},{"screen":"Legacy 6381 fallback display","why":"Collections may mix standards.","covers":["6381 only","7409 only","Mixed"],"include":["Unified display layer","Migration note in advanced"]}],"mentalModel":[{"label":"Reaction","description":"Unicode emoji string attached to NFT by user."},{"label":"Registry","description":"Public repository aggregating reactions cross-app."},{"label":"Skin tone modifier","description":"Fitzpatrick codes combine with base emoji."},{"label":"Variable length","description":"Some emoji multi-codepoint — render as single glyph."},{"label":"6381 legacy","description":"Older encoding — migrate display for compatibility."}],"statesToDesign":[{"state":"No reactions yet","trigger":"First visitor.","userNeed":"Discover feature.","designResponse":"Subtle Add reaction affordance."},{"state":"User reacted","trigger":"Connected wallet reacted.","userNeed":"Change or remove.","designResponse":"Highlight your emoji; tap to change."},{"state":"Picker open","trigger":"User adds reaction.","userNeed":"Find emoji including tones.","designResponse":"Full picker with search."},{"state":"Cross-device render diff","trigger":"Unsupported glyph.","userNeed":"Not broken boxes.","designResponse":"Fallback placeholder with tooltip."},{"state":"Reaction tx pending","trigger":"On-chain reaction submitting.","userNeed":"Optimistic UI.","designResponse":"Show pending reaction gray until confirm."}],"designDecisions":[{"question":"Group skin tone variants in counts?","recommendation":"Separate counts per exact string; optional rollup in analytics only.","rationale":"👍 vs 👍🏽 are distinct user expressions."},{"question":"On-chain vs off-chain reactions?","recommendation":"Match product — if on-chain show pending tx state.","rationale":"Cost vs permanence tradeoff."},{"question":"Picker search?","recommendation":"Required for expanded set.","rationale":"Full Unicode too large to browse only."}],"problemsSolved":[{"problem":"Limited reaction set","oldWay":"6381 constrained encoding","newWay":"Full Unicode string emoji","impact":"medium"},{"problem":"No skin tone representation","oldWay":"Yellow only emoji","newWay":"Tone modifiers in picker","impact":"medium"},{"problem":"Silent NFT social layer","oldWay":"No reactions on art","newWay":"Cross-app emote registry on any NFT","impact":"low"}],"uxPatterns":[{"name":"NFT Emoji Reaction Bar","description":"Quick react plus counts under NFT.","mockup":"concept/reactions","components":["ReactionBar","EmojiCount","AddButton"],"userFlow":["View NFT","Tap emoji","Count updates","Others see reaction"]},{"name":"Full Unicode Picker","description":"Skin tone support and search.","components":["EmojiPicker","SkinTonePopover","SearchField"],"userFlow":["Open picker","Long press for tone","Select","Reaction posts"]}],"antiPatterns":[{"pattern":"6381-only picker without tones","why":"7409 upgrade value lost","instead":"Full Unicode picker with modifiers","severity":"medium"},{"pattern":"Broken tofu boxes for valid emoji","why":"Looks broken","instead":"Font fallback stack and placeholder","severity":"high"},{"pattern":"Reactions without remove/change","why":"Regret permanent wrong emoji","instead":"Tap your reaction to edit","severity":"medium"}],"vocabulary":[{"use":"React","avoid":"Post emote to registry","why":"Social verb."},{"use":"Reactions","avoid":"Emote repository entries","why":"Familiar social term."},{"use":"Change reaction","avoid":"Update emote string","why":"Edit action language."}],"technicalNotes":"ERC-7409 uses string emoji values and supersedes ERC-6381's bytes4-compatible encoding. Handle multi-codepoint glyphs, reversible reaction state, and legacy display separately; counts remain wallet activity and do not establish unique-human sentiment.","relatedStandards":[{"id":"ERC-6381","relationship":"Prior emote standard superseded"},{"id":"ERC-721","relationship":"Reactions attach to any NFT"}],"keyTakeaways":["ERC-7409 is the Final successor to ERC-6381 with string-based emoji encoding.","Render multi-codepoint and skin-tone variants as user-selected strings.","Keep active reaction state, event history, and wallet-based counts distinct.","Label legacy ERC-6381 compatibility separately."]},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-7409","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-7409","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-7409","markdown":"https://www.eipsfordesigners.com/standards/ERC-7409/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-7409/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-7409","official":"https://ercs.ethereum.org/ERCS/erc-7409","discussion":"https://ethereum-magicians.org/search?q=ERC-7409"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}