Skip to content

Session Management

Control authenticated wallet sessions

The Wallet SDK creates a session after any successful authentication flow: passkey, email OTP, magic link, or Google OAuth. The session lets the SDK reconnect the ZeroDev Wagmi connector across reloads and sign wallet actions without asking the user to log in again each time.

For most apps, the defaults are enough.

Session lifecycle

Authenticate -> session created -> reconnect on reload -> refresh before expiry -> re-authenticate if expired

The connector checks for an existing session when your app loads. If the session is valid, Wagmi reconnects and useAccount returns the wallet address.

Configure session behavior

Session behavior is configured on the ZeroDev connector.

import { zeroDevWallet } from '@zerodev/wallet-react'
import { arbitrumSepolia } from 'wagmi/chains'
 
const projectId = '<your-project-id>'
const aaUrl = '<your-chain-specific-zerodev-rpc-url>'
 
zeroDevWallet({
  projectId,
  aaUrl,
  chains: [arbitrumSepolia],
  autoRefreshSession: true,
  sessionWarningThreshold: 120_000,
})
  • autoRefreshSession refreshes the session before it expires. The default is true.
  • sessionWarningThreshold controls how early the SDK refreshes the session before expiry.

Set autoRefreshSession: false only if you want to handle expiry yourself.

Refresh a session manually

Use useRefreshSession if your app wants an explicit refresh action.

import { useRefreshSession } from '@zerodev/wallet-react'
 
export function RefreshSessionButton() {
  const refreshSession = useRefreshSession()
 
  return (
    <button
      type="button"
      disabled={refreshSession.isPending}
      onClick={() => refreshSession.mutate({})}
    >
      {refreshSession.isPending ? 'Refreshing...' : 'Refresh session'}
    </button>
  )
}

Detect disconnected sessions

When a session expires and cannot be refreshed, the connector disconnects. Use Wagmi's useAccount hook to update your UI.

import { useAccount } from 'wagmi'
 
export function SessionStatus() {
  const { address, status } = useAccount()
 
  if (status === 'connected') {
    return <p>Connected: {address}</p>
  }
 
  if (status === 'reconnecting') {
    return <p>Reconnecting...</p>
  }
 
  return <p>Signed out</p>
}

Use custom storage

On the web, sessions use browser storage by default. Provide a custom storage adapter if your environment needs something else.

import type { StorageAdapter } from '@zerodev/wallet-core'
import { arbitrumSepolia } from 'wagmi/chains'
 
const projectId = '<your-project-id>'
const aaUrl = '<your-chain-specific-zerodev-rpc-url>'
 
const sessionStorageAdapter: StorageAdapter = {
  getItem: async (key) => window.sessionStorage.getItem(key),
  setItem: async (key, value) => window.sessionStorage.setItem(key, value),
  removeItem: async (key) => window.sessionStorage.removeItem(key),
}
 
zeroDevWallet({
  projectId,
  aaUrl,
  chains: [arbitrumSepolia],
  sessionStorage: sessionStorageAdapter,
})

Custom storage is also required in environments that do not provide browser localStorage, such as React Native.

Next steps