Auto-Sign: Eliminating Wallet Pop-ups for Real-Time Applications
Every blockchain interaction that requires a wallet signature creates friction. In a turn-based game, you might tolerate one pop-up per move. But in a real-time game, you need dozens of signatures per minute, and each pop-up breaks the flow completely. Auto-sign fixes this by delegating non-financial signing to a session key: your wallet approves once, then the app signs on your behalf for the rest of the session.

The problem with wallet pop-ups
Blockchain games need cryptographic signatures to prove that a player authorized each action. Without auto-sign, every game move triggers a wallet confirmation dialog ("Sign this transaction?"). The result is an experience that feels nothing like a game and everything like filling out forms. Real-time gameplay is basically impossible under these conditions.
How auto-sign works
The core insight is separating two types of blockchain interactions:
- Financial transactions (asset transfers, token minting, contract calls with value) always require explicit wallet approval
- Non-financial data submissions (game moves, messages, state updates) can be safely delegated to a session key
When a player starts a session, their wallet generates a temporary key pair and signs a delegation certificate. This certificate authorizes the session key to submit non-financial data on the player's behalf. The session key is scoped (can only submit game data, never move funds), time-bounded (expires when the session ends), and revocable (the player can cancel delegation at any time).
This preserves the security guarantees players expect: nobody can move their assets without explicit approval. It just removes the friction that makes real-time apps unusable.
Implementation in @effectstream/wallets
Auto-sign lives in the @effectstream/wallets package, which provides multi-chain wallet support for EffectStream applications. The package handles the full delegation lifecycle: key generation, certificate signing, session management, and automatic signing of non-financial transactions.
The wallet layer supports multiple chains (EVM via injected providers and Ethers, Cardano, Midnight, Polkadot, Algorand, and Mina), and auto-sign works across all of them through a unified API. Developers don't need chain-specific signing logic; the framework handles the differences. Full reference is in the wallets documentation.
The three-step flow in Safe Solver is representative of every game on midnight.fun:
import {
WalletMode,
walletLogin,
allInjectedWallets,
} from "@effectstream/wallets";
// 1. Initialize a local session wallet, silent and persisted in
// encrypted browser storage. preferBatchedMode enables auto-sign.
const localWalletResult = await walletLogin({
mode: WalletMode.EvmEthers,
preferBatchedMode: true,
connection: {
metadata: { name: "session", displayName: "Session Wallet" },
api: await getLocalSignerFromStorage(),
},
});
// 2. Let the user connect their real wallet (Midnight Lace in this
// example) — this is the only step that shows a pop-up.
const injected = await allInjectedWallets({
signatureSupport: false,
transactionSupport: false,
});
const midnightWallet = injected[WalletMode.Midnight][0];
const realWalletResult = await walletLogin({
mode: WalletMode.Midnight,
preference: { name: midnightWallet.metadata.name },
});
// 3. One-time delegation: the real wallet signs a message
// authorising the session wallet to submit non-financial inputs
// on its behalf. After this point, gameplay is silent.
await effectStreamService.connectWallets(
localWalletResult.result,
realWalletResult.result,
);
// 4. Every subsequent game input is signed by the session wallet —
// no pop-ups for the rest of the session.
await sendGameMove({ move: "x10y20" });
The signing model is uniform regardless of chain: WalletMode.Midnight could be swapped for WalletMode.EvmInjected, WalletMode.Cardano, or any other supported chain and the rest of the flow stays the same.
Live on midnight.fun
Auto-sign is live and in production on midnight.fun, powering three games:
- Safe Solver - a puzzle game where auto-sign lets you submit moves rapidly
- Kachina Kolosseum - PvP combat where timing matters and pop-ups would ruin the experience
- Block Kart Legends - racing where dozens of state updates happen per session

The difference is immediately noticeable. Players approve wallet access once when connecting, then play freely. A typical Safe Solver session generates 20-30 signatures, all handled by the session key in the background.
Before and after
Without auto-sign: Connect wallet → Start game → Pop-up → Approve → Make move → Pop-up → Approve → Make move → Pop-up → Approve → ... (player gives up after 3 moves)
With auto-sign: Connect wallet → Approve delegation → Play freely for the entire session → Done
The gameplay goes from "blockchain app with constant interruptions" to "normal game that happens to be on-chain." And it's not just games: chat apps, collaborative tools, IoT dashboards, anything that needs rapid interaction benefits from session key delegation. The security model (limited scope, time-bounded, revocable) applies to all of them.