EIP-712 meta-transactions: secure gasless UX, explained
Gasless UX is a product win. Meta-tx relayers are a security surface. Here's how to ship both safely.
Gasless UX is a product win. Meta-tx relayers are a security surface. Here's how to ship both safely.
The biggest Web3 UX win of 2024-26 has been gasless transactions. Users sign a typed message, a relayer submits on-chain, the user never touches ETH. EIP-712 + ERC-2771 make it standard. But every meta-transaction architecture has security trade-offs worth understanding before shipping.
EIP-712 gives signatures a typed, domain-separated structure. MetaMask renders 'You are about to sign: transfer 100 USDC to 0xabc...' instead of a 0x-garbage hex string. Dramatic drop in phishing success rates vs raw eth_sign.
struct ForwardRequest {
address from;
address to;
uint256 value;
uint256 gas;
uint256 nonce;
bytes data;
}
bytes32 private constant _TYPEHASH = keccak256(
"ForwardRequest(address from,address to,uint256 value,uint256 gas,uint256 nonce,bytes data)"
);A signed message without a nonce can be replayed until the contract is drained. Every meta-tx needs a per-user nonce, incremented on each successful call. Must be sequential · skipping a nonce lets a relayer grief by posting an old one.
An EIP-712 domain includes chainId. Without it, a signature valid on Arbitrum could be replayed on Optimism. Include chainId even if you think you're single-chain · forks exist.
Old libraries accepted (r, s, v) + (r, -s, v') as both valid for the same message. Solidity's ECDSA.recover now rejects high-s values; use OpenZeppelin's library, not custom recovery.
If the relayer pays gas but never recoups, any user can drain it. Mitigations: gas budgets per user, ERC-20 gas tokens as repayment, meta-tx only on specific allowlisted functions, rate limits.
Even with EIP-712, a signature for `approve(0xattacker, MAX_UINT)` renders clearly but looks legit if the user doesn't read carefully. Consider adding a human-readable description field or using permit2 with expiry timestamps.
Your backend signs and submits meta-txs as it sees fit. Full control, full responsibility. Cost: your ETH + infra. Good for dApps where you want tight policy control and already pay for ops.
Third-party relayer-as-a-service. Pay per tx or subscribe. Gelato's SDK is clean, Biconomy has better support for EIP-4337 (account abstraction). Best for fast-to-ship products.
The native account-abstraction standard. Users have smart-contract accounts; bundlers submit UserOps. Gold standard for the long run, more infra complexity up front. Production-ready on Arbitrum, Base, Optimism, Polygon.

Founder, DField Solutions
I'm a full-stack engineer and I build across the whole stack myself · AI agents, web and mobile apps, blockchain, backends, security, right down to the OS layer. If it's software, I've probably built it and broken it.
Let's talk about your project. 30 minutes, no strings.