{"id":"ERC-7066","name":"Lockable Extension for ERC-721","status":"Final","chain":"both","category":{"id":"nft","name":"NFT Capabilities","description":"What NFTs can do beyond basic ownership"},"journeyStages":[{"id":"management","name":"Asset Management","description":"Managing assets over time"}],"uxImpact":"NFTs can be locked in owner's wallet — usable but non-transferable until unlocked. Design implications: show 'Locked' status badge with locker address, enable lock/unlock flows with locker assignment, indicate locked tokens differently from transferable ones, show who can unlock. Design decisions: how to explain lock vs soulbound difference, whether locked tokens appear in marketplace listings, transferAndLock flow complexity, safety messaging about cold wallet as unlocker.","hasDetailedContent":true,"content":{"id":"ERC-7066","sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-7066","type":"official-spec"}],"lastReviewed":"2026-05-25","lastUpdated":"2026-05-25","summary":"NFTs can be locked in owner's wallet — usable but non-transferable until unlocked.","designerTakeaways":["You can show Locked badge with who can unlock on every locked token.","Your lock flow can recommend cold wallet as locker with safety copy.","You can block marketplace List while locked with explanation, not disabled mystery button."],"applicability":{"whenToUse":["High-value NFTs need anti-theft lock without full cold storage.","Games require usable but non-transferable state.","Locker address is separate trusted key."],"whenToAvoid":["Soulbound tokens with no unlock path.","Users need frequent transfers — lock adds friction.","Marketplace primary use case for asset."]},"prototypeFirst":[{"screen":"Lock asset flow","why":"Owner chooses anti-theft lock before threat.","covers":["Unlocked","Select locker","Confirm lock"],"include":["Locker address field","Cold wallet tip","Usable but not transferable note"]},{"screen":"Locked asset detail","why":"Daily view must show lock status clearly.","covers":["Locked by self","Locked by other locker"],"include":["Locked chip","Unlock authority","Use in app still enabled"]},{"screen":"Unlock confirmation","why":"Unlocking restores transfer — high risk moment.","covers":["Unlock success","Wrong locker fails"],"include":["Scary confirm copy","2-step confirm","Explorer link"]},{"screen":"Blocked listing while locked","why":"Marketplace must pre-check lock.","covers":["List blocked"],"include":["Cannot list while locked","Unlock first CTA"]}],"mentalModel":[{"label":"Locked","description":"Token cannot transfer; may still work in approved apps."},{"label":"Locker","description":"Address authorized to unlock — often cold wallet."},{"label":"Owner","description":"Still owns token; may or may not unlock depending on config."},{"label":"Lock vs soulbound","description":"Lock is temporary and reversible; soulbound is policy-level permanent."},{"label":"transferAndLock","description":"Send to new owner already locked — preview both transfer and lock."}],"statesToDesign":[{"state":"Unlocked — normal","trigger":"No active lock.","userNeed":"Transfer and sell freely.","designResponse":"Standard actions plus optional Lock asset."},{"state":"Locked — owner can unlock","trigger":"Owner is locker.","userNeed":"Use in app; unlock when ready to sell.","designResponse":"Locked badge with Unlock CTA."},{"state":"Locked — external locker","trigger":"Cold wallet is locker.","userNeed":"Know must use cold key to unlock.","designResponse":"Locked by [address] with connect cold wallet hint."},{"state":"List blocked","trigger":"User tries marketplace list.","userNeed":"Understand lock prevents sale.","designResponse":"Unlock to list message before wallet."},{"state":"transferAndLock incoming","trigger":"Receiving locked token.","userNeed":"Know incoming asset is locked.","designResponse":"Receive preview shows Locked on arrival."}],"designDecisions":[{"question":"Recommend cold wallet as locker?","recommendation":"Yes with default suggestion and explainer.","rationale":"Hot wallet as locker defeats anti-theft purpose."},{"question":"Show locked items in marketplace search?","recommendation":"Hide or badge Locked — do not allow list flow.","rationale":"Prevent failed listings and buyer confusion."},{"question":"Explain lock vs soulbound?","recommendation":"Tooltip: Locked = you chose protection; Soulbound = issuer rule.","rationale":"Users conflate two restriction types."}],"problemsSolved":[{"problem":"Hot wallet drain steals NFTs","oldWay":"Transfer out instantly on compromise","newWay":"Lock blocks transfer while app use continues","impact":"critical"},{"problem":"Cold storage removes utility","oldWay":"Move to vault, cannot use in game","newWay":"Locked but usable in connected apps","impact":"high"},{"problem":"Accidental listing of locked item","oldWay":"Listing fails at settlement","newWay":"Pre-check lock before list UI","impact":"medium"}],"uxPatterns":[{"name":"Lock Asset Flow","description":"Assign locker and confirm anti-theft lock.","mockup":"concept/nft-gallery","components":["LockButton","LockerInput","SafetyCopy"],"userFlow":["User taps Lock","Sets locker","Confirms","Locked badge appears"]},{"name":"Locked Status Badge","description":"Persistent locked indicator with unlock path.","mockup":"concept/verify-safety","components":["LockedChip","UnlockCTA","LockerLabel"],"userFlow":["View locked NFT","See locker","Unlock when ready","Transfer enabled"]}],"seenInTheWild":[{"app":"ERC-6147 Guard","url":"https://eips.ethereum.org/EIPS/eip-6147","note":"Related guard patterns for transfer restriction UX."},{"app":"OpenSea","url":"https://opensea.io/","note":"Listing restriction patterns for non-transferable states."},{"app":"MetaMask","url":"https://metamask.io/","note":"Wallet security flows inform locker assignment copy."}],"antiPatterns":[{"pattern":"Lock without explaining locker role","why":"Users lock themselves out permanently","instead":"Cold wallet recommendation and locker explainer","severity":"critical"},{"pattern":"Disabled List with no reason","why":"Users think marketplace bug","instead":"Cannot list while locked — Unlock first","severity":"high"},{"pattern":"Conflating lock with soulbound","why":"Wrong recovery expectations","instead":"Distinct Locked vs Non-transferable badges","severity":"medium"}],"vocabulary":[{"use":"Locked for protection","avoid":"Transfer restricted flag","why":"Security framing."},{"use":"Unlock with [locker]","avoid":"Call unlock() from locker EOA","why":"Action and actor, not function."},{"use":"Still usable here","avoid":"Lock does not affect utility hook","why":"Reassurance for gamers."}],"onMonad":[{"aspect":"Lock/unlock cost","ethereum":"Users hesitate to lock due to gas","monad":"Cheap lock/unlock enables proactive protection","designImplication":"Promote lock after high-value mint on Monad."},{"aspect":"Game integration","ethereum":"Locked state sync lag","monad":"Fast finality keeps game and wallet lock state aligned","designImplication":"Refresh lock status after every game session."}],"technicalNotes":"ERC-7066 lock differs from soulbound — always show locker and unlock path.","relatedStandards":[{"id":"ERC-6147","relationship":"Guard-based transfer restriction alternative"},{"id":"ERC-6454","relationship":"Transfer detection when locked"}]},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-7066","type":"official-spec"},{"label":"Discussion","url":"https://ethereum-magicians.org/search?q=ERC-7066","type":"discussion"},{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/erc-7066","type":"official-spec"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-7066","markdown":"https://www.eipsfordesigners.com/standards/ERC-7066/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-7066/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-7066","official":"https://eips.ethereum.org/EIPS/erc-7066","discussion":"https://ethereum-magicians.org/search?q=ERC-7066"},"freshness":{"lastReviewed":"2026-05-25","lastUpdated":"2026-05-25"}}