> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endstate.io/llms.txt
> Use this file to discover all available pages before exploring further.

# useWallet

> The provisioned customer wallet: its account address, provisioning status, session expiry, and the ready/refresh controls.

```ts theme={null}
function useWallet(): {
  account: WalletAccount | null;
  status: WalletStatus;
  error: Error | null;
  ready: () => Promise<WalletAccount>;
  refresh: () => Promise<WalletAccount>;
  expiresAt: Date | null;
};

type WalletStatus =
  | "unconfigured"
  | "idle"
  | "provisioning"
  | "ready"
  | "error";
```

`useWallet` reports the wallet [`EndstateProvider`](/sdks/web/reference/react/EndstateProvider) provisions from its `wallet` config. When the config's `enabled` gate is open, the provider mounts the frame and establishes a session automatically, so `account` populates on its own and `status` walks `idle` -> `provisioning` -> `ready`. You rarely call `ready()` directly - [`useClaim`](/sdks/web/reference/react/useClaim) resolves the address for you - but it is there when you need the address explicitly.

This version provisions and reports the account; it deliberately exposes no signing surface. Signing arrives in a later minor release.

## Example

```tsx theme={null}
"use client";
import { useWallet } from "@endstate-sdk/web/react";

export function WalletBadge() {
  const { account, status } = useWallet();

  if (status === "unconfigured") return null; // no wallet on this provider
  if (status === "idle") return <p>Sign in to set up your wallet.</p>;
  if (status === "provisioning") return <p>Setting up your wallet...</p>;
  if (status === "error") return <p>Wallet unavailable.</p>;

  return <p>Wallet ready: {account?.address}</p>;
}
```

## Returns

<ResponseField name="account" type="WalletAccount | null">
  The provisioned account (`{address}`), or `null` until provisioning resolves.
  See [`WalletAccount`](/sdks/web/reference/wallet/WalletAccount).
</ResponseField>

<ResponseField name="status" type="WalletStatus">
  `"unconfigured"` when no `wallet` config was passed to the provider; `"idle"`
  when configured but the `enabled` gate is still closed; `"provisioning"` while
  the frame mounts and the session establishes; `"ready"` once the account
  exists; `"error"` when provisioning failed. Branch the UI on this.
</ResponseField>

<ResponseField name="error" type="Error | null">
  The failure that moved `status` to `"error"`, or `null`. Branch on
  `error.code` (an `EndstateWalletError` carries `wallet.*` codes), never on the
  message. `wallet.session_expired` is the signal to call `refresh()`.
</ResponseField>

<ResponseField name="ready" type="() => Promise<WalletAccount>">
  Resolves the account, awaiting provisioning already in flight. Rejects with a
  typed error when no wallet is configured or the gate is closed.
</ResponseField>

<ResponseField name="refresh" type="() => Promise<WalletAccount>">
  Starts a fresh wallet session and returns the account. The remedy for a
  `wallet.session_expired` failure.
</ResponseField>

<ResponseField name="expiresAt" type="Date | null">
  When the current wallet session lapses, or `null` before one exists. After it
  passes, calls fail with `wallet.session_expired`; call `refresh()`.
</ResponseField>

## See also

<CardGroup cols={2}>
  <Card title="EndstateProvider" icon="square-code" href="/sdks/web/reference/react/EndstateProvider">
    Configure the wallet and its auth gate.
  </Card>

  <Card title="useClaim" icon="hand" href="/sdks/web/reference/react/useClaim">
    Claim into this wallet in a single call.
  </Card>

  <Card title="WalletAccount" icon="wallet" href="/sdks/web/reference/wallet/WalletAccount">
    The account shape this hook returns.
  </Card>

  <Card title="Wallet" icon="book-open" href="/sdks/web/wallet">
    The provisioning lifecycle and the identity credential.
  </Card>
</CardGroup>
