Open a session
The user signs one EIP-712 message. After that, a generated key signs. The wallet is not prompted again.
A session is a grant: an EIP-712 message the user signs with their wallet. The message names a freshly generated secp256k1 key, an expiry (one hour by default), the hub’s current session epoch, and the selectors that key may call. The app verifies the signature on every call and resolves _actor() to the granter, so your contract sees the user, never the key.
const session = await interlude.openSession({
wallet, // the user's wallet. Prompted exactly once.
scope: ["play"], // First hour. The demo uses join / move / …
ensureChain: true, // switch the wallet to Monad testnet first
});
session.granter; // the user. What the app's _actor() returns.
session.sessionKey; // the generated key. Holds no funds.
session.expiresAt; // one hour by default.Which wallet
wallet is a viem WalletClient that carries an account. In the browser, build it on custom(window.ethereum) as on First hour; with wagmi it is useWalletClient().data, as is. A client with no account throws SessionUnusableError. ensureChain: true asks the wallet to switch to Monad testnet, and to add it if it does not know it, before the prompt; without it, a wallet on another network throws WrongChainError and nothing is signed. A process holds a key instead (Agents).
What the wallet prompt says
A grant with no scope authorises nothing. That is deliberate: the prompt should say only join and move, not "this site can do anything". Pass anyFunction: true only when you mean a blanket grant. Overloads take the full signature.
The SDK fills in the parts that are easy to get wrong. chainId is Monad’s, not the node’s. verifyingContract is the app. The epoch is hub.sessionEpochOf(granter) as of signing: a grant that names an old epoch is stale on arrival on Monad. A running node read the epoch at its pinned block, so there the revoke lands only with the next delegation (see revoke).
Refresh does not prompt again
openSession restores from sessionStorage before it opens the wallet. A refresh mid-game costs the user nothing, as long as the grant has not expired and they have not revoked. The cost of that convenience is on the revoke page.
