useSession({ address }) calls the active modality’s
session-creation callback on mount and on a 50-minute interval,
keeping the 1-hour calm_session cookie fresh ahead of expiry. It
also refetches when the tab regains focus — backgrounded tabs throttle
the timer, so focus revalidation catches the “user came back after 2h
idle” case before the next call would 401.
Import
Usage
app/page.tsx
<SignedIn> calls useCalm(), which throws outside the Calm
context. Gate it on useReady() (from @calm-xyz/react/wagmi or
@calm-xyz/react/privy) so the inner component only renders once
the provider is live.
Parameters
address
string
The wallet address the session is bound to. Must match the wallet the
active provider is configured for.
Return Type
UseQueryResult<SessionResponse, ApiError> from
@tanstack/react-query — the SDK’s query
client is set up by the active modality provider.
data
SessionResponse | undefined
The session-creation response: { wallet, expires_at }. wallet is
lowercased and 0x-prefixed; expires_at is the ISO timestamp the
calm_session cookie expires at (1 hour from creation).
isPending
boolean
true until the first session-creation call resolves. Use to gate
loading UI.
error
ApiError | null
The structured error from the modality’s createSession callback.
Branch on error.code to drive recovery UI (e.g. siwe_invalid,
binding_expired, refresh_wallet_mismatch).
status
"pending" | "error" | "success"
The react-query status — useful when you want one value to switch on
in a switch rather than three booleans.
refetch
() => Promise<UseQueryResult<SessionResponse, ApiError>>
Manually trigger a session refresh — useful after the partner does
something that may have invalidated the cookie (e.g. their own wallet
stack’s logout). useCalm().logout()
invalidates the same query under the hood, so most callers don’t need
this directly.
See the @tanstack/react-query useQuery docs
for the full set of fields on the return type.