# Session Management (/wallets/session-management)

> For the complete documentation index, see [llms.txt](/llms.txt)



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 [#session-lifecycle]

```txt
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 [#configure-session-behavior]

Session behavior is configured on the ZeroDev connector.

```tsx
import { zeroDevWallet } from '@zerodev/wallet-react'
import { arbitrumSepolia } from 'wagmi/chains'

const projectId = '<your-project-id>'
const aaHost = 'https://rpc.zerodev.app'

zeroDevWallet({
  projectId,
  aaHost,
  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 [#refresh-a-session-manually]

Use `useRefreshSession` if your app wants an explicit refresh action.

```tsx
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 [#detect-disconnected-sessions]

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

```tsx
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 [#use-custom-storage]

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

```tsx
import type { StorageAdapter } from '@zerodev/wallet-core'
import { arbitrumSepolia } from 'wagmi/chains'

const projectId = '<your-project-id>'
const aaHost = 'https://rpc.zerodev.app'

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,
  aaHost,
  chains: [arbitrumSepolia],
  sessionStorage: sessionStorageAdapter,
})
```

Custom storage is also required in environments that do not provide browser `localStorage`, such as React Native  — see [React Native Configuration](/wallets/react-native/configuration) for the storage adapters the SDK ships for Expo.

## Next steps [#next-steps]

* [Send a transaction](/wallets/wallet-api/send-transaction)
* [Sign a message](/wallets/wallet-api/sign-message)
* Integrate other login methods: [Passkeys](/wallets/auth/passkeys), [Email OTP](/wallets/auth/email-otp), [Magic Link](/wallets/auth/magic-link), or [Google OAuth](/wallets/auth/google-oauth)
