> ## 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.

# createWallet

> Mounts the Endstate wallet frame and starts session establishment immediately. Provisions and reports the account; no signing surface in this version.

```ts theme={null}
function createWallet(options: CreateWalletOptions): EndstateWallet;
```

The wallet lives in an iframe on an Endstate origin. `createWallet` mounts that frame, establishes a session from the identity credential your callback supplies, and reports the account. Key material never reaches your page.

Setup starts at creation, not at `ready()`. Create the wallet on page load and `await wallet.ready()` where the account is needed - first-time setup can take several seconds and should never sit inside a user action.

## Example

```ts theme={null}
import { createWallet } from "@endstate-sdk/web";

const wallet = createWallet({
  publishableKey: "end_pk_live_...",
  // Called fresh for every session establishment; never return a cached value.
  getIdentityToken: () => mintIdentityToken(),
});

const { address } = await wallet.ready();
```

## Parameters

<ParamField body="publishableKey" type="EndstatePublishableKey" required>
  Your publishable key (`end_pk_...`). A secret key is rejected here, by the
  type and again at runtime - a non-`end_pk_` value throws a `TypeError`, and
  the value is deliberately not echoed because the common mistake is pasting a
  secret key into browser code.
</ParamField>

<ParamField body="getIdentityToken" type="() => string | Promise<string>" required>
  Supplies the identity credential the session is established from. It is called
  fresh for every session establishment - on `ready()` and again on each
  `refreshSession()` - and must never return a cached value. The credential is a
  dedicated, single-use wallet credential for the signed-in customer that
  expires in about a minute; returning a session token, a reused token, or a
  stale value guarantees a later failure. Where it comes from depends on how
  your customers sign in: with Endstate-managed identity it is issued against
  the customer's Endstate sign-in, and with [bring your own
  auth](/external-auth) your backend mints it from your own login. Must resolve
  with a non-empty string, or a `TypeError` is thrown.
</ParamField>

<ParamField body="environment" type="&#x22;production&#x22;" default="production">
  Which deployed wallet to mount. `"production"` (`https://wallet.endstate.io`)
  is the environment available to your organization, and the default. Other
  environments are reserved for Endstate internal use. The frame origins are
  compiled into the package and are not otherwise configurable - a security
  property of the design.
</ParamField>

<ParamField body="container" type="HTMLElement" default="document.body">
  Where the hidden frame is appended. The frame is mounted `aria-hidden` and
  sized to zero; override this only when `document.body` is not the right mount
  point.
</ParamField>

<ParamField body="timeouts" type="{ frameReadyMs?: number; sessionMs?: number }">
  Wait budgets in milliseconds. `frameReadyMs` bounds the frame handshake
  (default `5000`); `sessionMs` bounds identity issuance, session establishment,
  and wallet setup (default `30000`). A stage that exceeds its budget fails with
  `wallet.timeout`.
</ParamField>

## Returns

[`EndstateWallet`](/sdks/web/reference/wallet/EndstateWallet) - a mounted wallet whose setup is already in flight. Read the account with `account()` or `await ready()`.

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

<Warning>
  `createWallet` runs in a browser document. On a server there is no frame to
  mount - it throws a `TypeError`. Hold the account address server-side instead.
</Warning>
