{"id":"ERC-2771","name":"Secure Meta Transactions","status":"Final","chain":"both","category":{"id":"onboarding","name":"Onboarding & Access","description":"Getting users into web3 without friction"},"journeyStages":[{"id":"executing","name":"Executing Transactions","description":"Performing on-chain actions"}],"uxImpact":"Users submit transactions without holding ETH — a relayer pays gas fees on their behalf (meta-transactions/gasless). Design implications: remove 'insufficient funds for gas' errors entirely, hide gas price selection for sponsored transactions, show clear indication when transactions are gasless vs user-paid, design relayer selection if multiple are available. Design decisions: decide who sponsors gas (dApp, protocol, user via different token), design fallback when relayer is unavailable or congested, consider showing original signer address vs relayer address in transaction history, handle trust model — users must understand their transaction goes through a forwarder.","hasDetailedContent":true,"content":{"id":"ERC-2771","summary":"ERC-2771 enables \"meta-transactions\" — someone else pays the gas for your transaction. A trusted forwarder relays your signed message and pays gas on your behalf. This means users can interact with dApps without holding ETH. Perfect for onboarding: the dApp sponsors the user's first transactions.","applicability":{"whenToUse":["Your product addresses: new users need ETH before doing anything.","Your product addresses: gas costs scare away new users.","The flow should deliver: sponsor pays gas, user starts immediately.","You are designing a sponsored transaction experience with visible states and recovery paths."],"whenToAvoid":["Clear: \"Sponsored by X\" and when sponsorship ends.","Offer: \"Pay gas yourself\" as fallback option.","Explain: \"Sign to authorize (no gas cost)\".","Wallet or chain support is fixed and users cannot choose providers."]},"designerTakeaways":["You can remove the buy-ETH-first dead end with sponsored or clearer fees.","You can design UI that delivers \"Claim for free\", sponsor covers gas.","You can standard trusted forwarder pattern."],"problemsSolved":[{"problem":"New users need ETH before doing anything","oldWay":"Buy ETH on exchange → wait → transfer → then interact","newWay":"Sponsor pays gas, user starts immediately","impact":"critical"},{"problem":"Gas costs scare away new users","oldWay":"\"$5 to claim free NFT? No thanks.\"","newWay":"\"Claim for free\" — sponsor covers gas","impact":"critical"},{"problem":"No standard for gasless transactions","oldWay":"Every relayer had different implementation","newWay":"Standard trusted forwarder pattern","impact":"high"}],"uxPatterns":[{"name":"Sponsored Transaction","description":"User action with no gas cost","mockup":"concept/typed-data","userFlow":["User sees reward to claim","App shows \"Sponsored\" gas","User clicks Claim","Signs message (not transaction)","Relayer submits and pays gas","User receives tokens"]},{"name":"Gasless Onboarding","description":"First actions without gas","mockup":"concept/wallet","userFlow":["New user connects wallet","No ETH required for first actions","Each action signed, not sent","Relayer pays all gas","User onboarded without friction"]}],"uiComponents":[{"name":"SponsoredGasIndicator","description":"Shows that gas is being paid by sponsor","states":["sponsored","partial","user-pays"],"props":["sponsor","savingsAmount"]},{"name":"GaslessButton","description":"Action button that uses meta-transaction","states":["idle","signing","relaying","success","error"],"props":["action","sponsor","onComplete"]},{"name":"RelayerStatus","description":"Shows relayer transaction status","states":["signing","queued","submitted","confirmed"],"props":["txHash","estimatedTime"]}],"antiPatterns":[{"pattern":"Not explaining sponsored gas","why":"Users confused when later asked to pay","instead":"Clear: \"Sponsored by X\" and when sponsorship ends","severity":"high"},{"pattern":"Hiding that it's a signature, not transaction","why":"Users don't understand what they're signing","instead":"Explain: \"Sign to authorize (no gas cost)\"","severity":"medium"},{"pattern":"No fallback when relayer is down","why":"Users stuck if relayer fails","instead":"Offer: \"Pay gas yourself\" as fallback option","severity":"high"}],"onMonad":[{"aspect":"Meta-tx Confirmation","ethereum":"Relayed tx takes 12+ seconds","monad":"Sub-second even through relayer","designImplication":"Gasless feels instant"},{"aspect":"Gas Costs","ethereum":"Sponsor saves user $5-20 per tx","monad":"Already cheap, but still useful for onboarding","designImplication":"Emphasize \"no ETH needed\" over savings"}],"keyTakeaways":["ERC-2771 = meta-transactions (someone else pays gas)","Perfect for onboarding new users","Always show who sponsors and for how long","User signs message, relayer pays gas","Have fallback for when relayer unavailable"],"technicalNotes":"ERC-2771 defines trusted forwarder pattern. User signs ForwardRequest (from, to, value, gas, nonce, data). Forwarder appends msg.sender (original signer) to calldata. Receiving contract uses _msgSender() which extracts original sender from calldata when called via trusted forwarder. isTrustedForwarder(forwarder) validates the forwarder."},"sources":[{"label":"Official specification","url":"https://eips.ethereum.org/EIPS/eip-2771","type":"official-spec"},{"label":"Discussion","url":"https://ethereum-magicians.org/search?q=ERC-2771","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-2771","markdown":"https://www.eipsfordesigners.com/standards/ERC-2771/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-2771/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-2771","official":"https://eips.ethereum.org/EIPS/eip-2771","discussion":"https://ethereum-magicians.org/search?q=ERC-2771"},"freshness":{"lastReviewed":"2026-04-05","lastUpdated":"2026-04-05"}}