DEV Community

ar1as1
ar1as1

Posted on

ZK Session Keys: Fix MetaMask Popups in Web3 Games with ERC-4337 Account Abstraction

Every Web3 game has the same problem — MetaMask keeps interrupting gameplay with popups. Shoot an enemy? Popup. Open a chest? Popup. Buy an item? Popup.

I built a solution: ZK Session Key Validator — sign once at the start, play the entire session without interruptions.

How It Works

  1. Player signs once at game start
  2. A temporary session key is created with strict rules:
    • Valid for 2 hours only
    • Max spend limit (e.g. 0.01 ETH)
    • Whitelisted contracts only
  3. All in-game actions auto-sign silently
  4. Session expires automatically

Zero-Knowledge Proof Security

Every transaction is validated by a Groth16 ZK proof (Circom circuit) that verifies:

  • Session commitment = Poseidon(masterKey, sessionAddr, nonce)
  • Target contract is in the Merkle whitelist
  • currentTime < expiry
  • spentSoFar + txValue ≤ spendLimit

No trust required — math enforces the rules on-chain.

Live on Sepolia Testnet

Contract Address
Groth16Verifier 0x99e61B9dC9C6889Dd2e249CC6183B6fa7A8795E3
SessionKeyValidator 0xc5655348C4E6e77AFF2BBb03A5758CaC205347Cf

Quick Start

import { Prover } from './prover.js';

const prover = await new Prover(RPC_URL, VALIDATOR_ADDRESS).init();

// Sign ONCE — 1 MetaMask popup
await prover.createSession(masterSigner, 7200, parseEther('0.01'), [gameContract], true);

// All actions — ZERO popup
const userOp = await prover.signAction(wallet, gameContract, callData);
Enter fullscreen mode Exit fullscreen mode

GitHub

Full source code, ZK circuit, and deployment scripts:
👉 https://github.com/ar1as1/session-game

Built with: Circom, SnarkJS, Ethers.js v6, Foundry, ERC-4337

Top comments (0)