---
title: "wavelength-react"
description: "React bindings for the Wavelength SDK - the WavelengthProvider component and hooks for balance, activity, and wallet operations."
canonical: https://wavelength.lightning.engineering/reference/wavelength-react/
---

> Docs index: https://wavelength.lightning.engineering/llms.txt

# wavelength-react

React bindings for the Wavelength SDK - the WavelengthProvider component and hooks for balance, activity, and wallet operations.

`@lightninglabs/wavelength-react` is the React binding for the Wavelength SDK: a context provider that hands a [`WalletEngine`](/reference/wavelength-core/#WalletEngine) down to a component subtree, plus hooks for reading its state and calling wallet operations.

> **One import for the contract**
>
> This package re-exports the complete `wavelength-core` contract, so you can import types directly from `@lightninglabs/wavelength-react` rather than adding `@lightninglabs/wavelength-core` as a separate dependency.

The engine itself is not built here: create one with `createWebWalletEngine` from [wavelength-web](/reference/wavelength-web/) or `createNativeWalletEngine` from [wavelength-react-native](/reference/wavelength-react-native/). Every hook on this page, including `useWalletPasskey`, must be called within a `WavelengthProvider` subtree; each throws if it is not.

## Provider

### WavelengthProvider

function

Context provider that hands a [`WalletEngine`](/reference/wavelength-core/#WalletEngine) down to descendants. Wrap your application root (or any subtree) with this component so child hooks can access wallet state and operations.

```ts
function WavelengthProvider(props: WavelengthProviderProps): JSX.Element
```

- `engine` [`WalletEngine`](/reference/wavelength-core/#WalletEngine)

  A WalletEngine from any transport, e.g. createWebWalletEngine() from wavelength-web or createNativeWalletEngine() from wavelength-react-native. Required; the provider throws synchronously if it is missing.

- `children` `ReactNode`

  The component subtree that can call Wavelength SDK hooks.

> **Note**
>
> **The provider owns nothing.** `WavelengthProvider` does not build, start, poll, or dispose anything: it publishes the engine you hand it to `useSyncExternalStore` subscribers. Every lifecycle behavior described below (sync polling, activity-driven refresh, `autoStart`, the `stopped` transition on an unsolicited runtime stop) is owned by the `WalletEngine` itself, so it also applies to a vanilla (non-React) consumer that drives the same engine directly. See [`WalletEngine`](/reference/wavelength-core/#WalletEngine) on the wavelength-core reference for the full behavior list.
>
> The provider never calls `engine.dispose()` on unmount. The code that constructed the engine (typically module scope, outside any component) owns its lifetime and is responsible for disposing it when the app is truly done with it.

### WavelengthProviderProps

type

Props for the `WavelengthProvider` component. `WavelengthProviderProps` is not itself an exported name; the props type is declared inline on the component’s destructured parameter. It is named and documented separately here only for readability.

```ts
type WavelengthProviderProps = {
  children: ReactNode;
  engine: WalletEngine;
};
```

### useWalletEngine

function

Returns the [`WalletEngine`](/reference/wavelength-core/#WalletEngine) from the nearest `WavelengthProvider`: the escape hatch for anything the granular hooks below do not cover (for example calling `engine.client` directly, or a method with no dedicated hook). Throws outside a provider.

```ts
function useWalletEngine(): WalletEngine
```

Returns: [`WalletEngine`](/reference/wavelength-core/#WalletEngine):

The provider’s engine instance.

## Runtime lifecycle

### useWallet

function

The application-shell hook: the lifecycle phase to route your top-level UI on, the last fatal runtime error, and the start/stop actions. There are no `pending` flags here: `phase === 'starting'` / `'stopping'` already encode them.

```ts
function useWallet(): {
  phase: RuntimePhase;
  error: Error | null;
  start(config?: RuntimeConfig): Promise<WalletInfo>;
  stop(): Promise<void>;
};
```

- `phase` [`RuntimePhase`](/reference/wavelength-core/#RuntimePhase)

  Current runtime/wallet lifecycle phase. See RuntimePhase on the wavelength-core reference; it includes 'restoring' while a background restore is bringing the wallet up.

- `error` `Error | null`

  The last fatal runtime-level error, or null. Set when the initial runtime load fails, when start()/stop() fails, or after the engine's background processes exhaust their failure budget (e.g. repeated sync-poll or background-refresh failures).

- `start(config?)` `(config?: RuntimeConfig) => Promise<WalletInfo>`

  Starts the runtime. Falls back to the engine's configured config (the one passed to createWebWalletEngine/createNativeWalletEngine) when called with no argument; throws if neither exists. Resolves with the WalletInfo from startup.

- `stop()` `() => Promise<void>`

  Stops the runtime and clears the in-memory snapshot (info/balance/activity reset to null/null/\[]); persisted wallet data is untouched.

Returns: `{ phase, error, start, stop }`:

The runtime lifecycle phase, last fatal error, and start/stop actions.

## Reading state

The five hooks below each subscribe to one slice of the engine’s snapshot via `useSyncExternalStore`, so a component re-renders only when the slice it reads actually changes. `useWalletInfo`, `useWalletBalance`, and `useWalletActivity` are plain selectors; `useWalletRecovery` and `useWalletLogs` also return an action (`acknowledge()` and `clear()` respectively) alongside their slice.

### useWalletInfo

function

The most recent complete wallet info, or `null` before the runtime reports it.

```ts
function useWalletInfo(): WalletInfo | null
```

Returns: `WalletInfo | null`:

The current `WalletInfo`, or `null` before the runtime reports it. Always a complete object: the engine refetches full info whenever the wallet comes up (create, unlock, passkey open, restore).

### useWalletBalance

function

The most recent wallet balance, or `null` before it is known.

```ts
function useWalletBalance(): Balance | null
```

Returns: `Balance | null`:

The current Balance, or null before known.

### useWalletActivity

function

The most recent activity entries, newest-first as returned by the daemon.

```ts
function useWalletActivity(): Entry[]
```

Returns: `Entry[]`:

Always the result of `list({ view: 'activity', pendingOnly: false })`; it does not reflect the vtxos or onchain views.

### useWalletRecovery

function

The background recovery status set by [`useWalletRestore`](#useWalletRestore) and its acknowledge action.

```ts
function useWalletRecovery(): {
  recovery: RecoveryState;
  acknowledge(): void;
};
```

- `recovery` [`RecoveryState`](/reference/wavelength-core/#RecoveryState)

  The background recovery status, a discriminated union on status: { status: 'idle' } | { status: 'restoring' } | { status: 'done', result: CreateWalletResult } | { status: 'failed', error: Error }. failed covers both a background scan that errored on an already-usable wallet and a restore that failed before the wallet came up at all, including an untracked restore; read phase from useWallet() alongside it to tell the two apart (ready vs. needsWallet). See RecoveryState on the wavelength-core reference. Drive a "restoring your balance and history" banner off the ready case, or a restore-failed message on the onboarding screen off the needsWallet case.

- `acknowledge()` `() => void`

  Resets recovery to { status: 'idle' }, e.g. after the user dismisses the banner.

### useWalletLogs

function

The buffered runtime log tail and a clear action.

```ts
function useWalletLogs(): {
  logs: WavelengthLogPayload[];
  clear(): void;
};
```

- `logs` `WavelengthLogPayload[]`

  Bounded tail (up to 200 entries) of 'log' events from the runtime, newest last.

- `clear()` `() => void`

  Clears the buffered log tail.

## Mutations

The eight hooks below drive a wallet operation and carry hook-local, verb-prefixed `*Pending`/`*Error`/`*Data` state, all built on one shared convention.

### The mutation convention

Every mutation hook exposes the same shape, with its fields prefixed by the verb it performs: an action function (e.g. `create`), `<verb>Pending: boolean`, `<verb>Error: Error | null`, `<verb>Data` (the last successful result, or `null`), and `reset<Verb>(): void`.

Calling the action clears the previous error and data, sets pending to `true`, awaits the underlying engine call, and on completion **both** updates the hook’s state **and** settles the returned promise the normal way: it resolves with the result (and sets the data field) or rejects with the failure (and sets the error field to that same `Error` instance). This is throw-and-capture: read the `*Error`/`*Data` fields for a declarative render, or `await`/`try`/`catch` the action’s return value for imperative flow, whichever fits the call site. Error fields are always `Error | null`, never a string. `reset<Verb>()` clears the pending/error/data trio back to idle without calling anything.

A `PasskeyCancelledError` (the user dismissed the OS prompt) is the one exception: it rethrows without being recorded into the error field, since a dismissed prompt is not a failure to display.

#### Why the verb prefix

A component composing several of these hooks (`create` and `deposit` side by side, say) never needs destructure aliases to avoid name collisions. [`useWalletPasskey`](#useWalletPasskey)’s `create`/`open` fields follow the same pattern, but this is the one place the prefix does not save you: `useWalletCreate` and `useWalletPasskey` both expose a `create` verb, so destructuring both in the same component collides on all four of `create`, `createPending`, `createError`, and `resetCreate`. Keep one as a namespaced object (`const passkey = useWalletPasskey(...)`) instead of destructuring both.

Each hook’s return type is also exported as `UseWallet<Verb>Result` (`UseWalletCreateResult`, `UseWalletRestoreResult`, `UseWalletUnlockResult`, `UseWalletDepositResult`, `UseWalletReceiveResult`, `UseWalletPrepareSendResult`, `UseWalletSendResult`, `UseWalletRefreshResult`, and the exit-hook result types documented in [Exiting Ark](#exiting-ark) below), for typing wrapper components around a hook without re-deriving its shape.

### useWalletCreate

function

Creates a new wallet, with hook-local createPending/createError/createData state.

```ts
function useWalletCreate(): {
  create(req: CreateWalletRequest): Promise<CreateWalletResult>;
  createPending: boolean;
  createError: Error | null;
  createData: CreateWalletResult | null;
  resetCreate(): void;
};
```

- `create(req)` `(req: CreateWalletRequest) => Promise<CreateWalletResult>`

  Creates a new wallet, refetches info, and kicks a background refresh. See createWallet on the wavelength-core reference.

Returns: `{ create, createPending, createError, createData, resetCreate }`:

See [the mutation convention](#the-mutation-convention).

### useWalletRestore

function

Restores a wallet from a mnemonic, with hook-local restorePending/restoreError/restoreData state.

```ts
function useWalletRestore(): {
  restore(req: RestoreWalletRequest): Promise<WalletInfo>;
  restorePending: boolean;
  restoreError: Error | null;
  restoreData: WalletInfo | null;
  resetRestore(): void;
};
```

- `restore(req)` `(req: RestoreWalletRequest) => Promise<WalletInfo>`

  Restores a wallet from req.mnemonic. See restoreWallet on the wavelength-core reference.

Returns: `{ restore, restorePending, restoreError, restoreData, resetRestore }`:

See [the mutation convention](#the-mutation-convention), with one twist: `restore`’s promise (and therefore `restorePending`/`restoreError`) only covers getting the wallet up; it resolves as soon as the restored wallet is usable, not when the optional server-assisted recovery scan finishes, and it never rejects for a scan failure. Observe the scan, and a restore that fails before the wallet came up, separately through [`useWalletRecovery`](#useWalletRecovery): even a fire-and-forget `restore()` call whose promise is not awaited still surfaces a pre-usability failure there once `phase` falls back to `'needsWallet'`.

### useWalletUnlock

function

Unlocks an existing wallet, with hook-local unlockPending/unlockError/unlockData state.

```ts
function useWalletUnlock(): {
  unlock(req: UnlockWalletRequest): Promise<UnlockWalletResult>;
  unlockPending: boolean;
  unlockError: Error | null;
  unlockData: UnlockWalletResult | null;
  resetUnlock(): void;
};
```

- `unlock(req)` `(req: UnlockWalletRequest) => Promise<UnlockWalletResult>`

  Unlocks an existing wallet, refetches info, and kicks a background refresh. See unlockWallet on the wavelength-core reference.

Returns: `{ unlock, unlockPending, unlockError, unlockData, resetUnlock }`:

See [the mutation convention](#the-mutation-convention).

### useWalletDeposit

function

Requests an on-chain deposit address, with hook-local depositPending/depositError/depositData state.

```ts
function useWalletDeposit(): {
  deposit(req?: DepositRequest): Promise<DepositResult>;
  depositPending: boolean;
  depositError: Error | null;
  depositData: DepositResult | null;
  resetDeposit(): void;
};
```

- `deposit(req?)` `(req?: DepositRequest) => Promise<DepositResult>`

  Requests an on-chain deposit address and kicks a background refresh. req is optional and defaults to {} when omitted. See deposit on the wavelength-core reference.

Returns: `{ deposit, depositPending, depositError, depositData, resetDeposit }`:

See [the mutation convention](#the-mutation-convention).

### useWalletReceive

function

Requests a Lightning receive invoice, with hook-local receivePending/receiveError/receiveData state.

```ts
function useWalletReceive(): {
  receive(req: ReceiveRequest): Promise<ReceiveResult>;
  receivePending: boolean;
  receiveError: Error | null;
  receiveData: ReceiveResult | null;
  resetReceive(): void;
};
```

- `receive(req)` `(req: ReceiveRequest) => Promise<ReceiveResult>`

  Requests a Lightning receive invoice and kicks a background refresh. See receive on the wavelength-core reference.

Returns: `{ receive, receivePending, receiveError, receiveData, resetReceive }`:

See [the mutation convention](#the-mutation-convention).

### useWalletPrepareSend

function

Quotes a payment without dispatching it, with hook-local preparePending/prepareError/prepareData state.

```ts
function useWalletPrepareSend(): {
  prepare(req: SendRequest): Promise<PrepareSendResult>;
  preparePending: boolean;
  prepareError: Error | null;
  prepareData: PrepareSendResult | null;
  resetPrepare(): void;
};
```

- `prepare(req)` `(req: SendRequest) => Promise<PrepareSendResult>`

  Quotes a payment without dispatching it; no refresh, since a quote moves no money. See prepareSend on the wavelength-core reference.

Returns: `{ prepare, preparePending, prepareError, prepareData, resetPrepare }`:

See [the mutation convention](#the-mutation-convention). `prepareData` holds the latest quote for a review screen; pair it with [`useWalletSend`](#useWalletSend)’s `sendPrepared` to dispatch it.

### useWalletSend

function

Dispatches a payment: `send` is the one-shot path, `sendPrepared` confirms a quote from [`useWalletPrepareSend`](#useWalletPrepareSend). The two verbs are alternative dispatch paths for the same payment and share one sendPending/sendError/sendData slot.

```ts
function useWalletSend(): {
  send(req: SendRequest): Promise<SendResult>;
  sendPrepared(prepared: PrepareSendResult): Promise<SendResult>;
  sendPending: boolean;
  sendError: Error | null;
  sendData: SendResult | null;
  resetSend(): void;
};
```

- `send(req)` `(req: SendRequest) => Promise<SendResult>`

  Quotes and dispatches a payment in one call, then kicks a background refresh. See send on the wavelength-core reference.

- `sendPrepared(prepared)` `(prepared: PrepareSendResult) => Promise<SendResult>`

  Dispatches a quote returned by useWalletPrepareSend, then kicks a background refresh. See sendPrepared on the wavelength-core reference.

Returns: `{ send, sendPrepared, sendPending, sendError, sendData, resetSend }`:

See [the mutation convention](#the-mutation-convention).

### useWalletRefresh

function

Re-fetches info, balance, and activity.

```ts
function useWalletRefresh(): {
  refresh(): Promise<void>;
  refreshPending: boolean;
  refreshError: Error | null;
  resetRefresh(): void;
};
```

- `refresh()` `() => Promise<void>`

  Re-fetches info, balance, and activity concurrently. See refresh on the wavelength-core reference.

Returns: `{ refresh, refreshPending, refreshError, resetRefresh }`:

The one mutation hook with no data field: `refresh()` resolves `void`, so there is nothing to hold. `refreshPending` tracks only this hook instance’s own calls, not the engine’s own background refreshes (the sync poll, the activity-driven settle reconcile, or the refresh kicked automatically after another mutation): those never flip it. Use it as what a pull-to-refresh spinner should show.

## Exiting Ark

Seven hooks cover the exit surface. `useWalletExit`, `useWalletExitPlan`, `useWalletSweep`, and [`useWalletList`](#useWalletList) are 1:1 wrappers around one [`WalletEngine`](/reference/wavelength-core/#WalletEngine) verb each, following the same mutation convention as the hooks above. [`useWalletExitBatch`](#useWalletExitBatch) is the orchestrator: it drives a full multi-outpoint exit through the funding-contention guards documented on [`exitBatch`](/reference/wavelength-core/#exitBatch) in the wavelength-core reference, and additionally exposes the batch’s progress events. [`useWalletExitStatus`](#useWalletExitStatus) and [`useWalletExits`](#useWalletExits) are read hooks instead of mutations: they fetch on mount (and on relevant changes) and expose a `refresh*` action rather than a `reset*` one, since there is no pending/error/data trio to clear back to idle, only a cached read to force fresh.

### useWalletExit

function

Starts a single exit for one outpoint, with hook-local exitPending/exitError/exitData state. A 1:1 wrapper around [`WalletEngine.exit()`](/reference/wavelength-core/#WalletEngine).

```ts
function useWalletExit(): {
  exit(req: ExitRequest): Promise<ExitResult>;
  exitPending: boolean;
  exitError: Error | null;
  exitData: ExitResult | null;
  resetExit(): void;
};
```

- `exit(req)` `(req: ExitRequest) => Promise<ExitResult>`

  Starts a single exit, cooperative or unilateral depending on req. Takes the full ExitRequest union; see exit on the wavelength-core reference.

Returns: `{ exit, exitPending, exitError, exitData, resetExit }`:

See [the mutation convention](#the-mutation-convention).

### useWalletExitPlan

function

Previews unilateral-exit readiness and backing-wallet funding for a set of outpoints, with hook-local planPending/planError/planData state. A 1:1 wrapper around [`WalletEngine.getExitPlan()`](/reference/wavelength-core/#WalletEngine). Pair it with [`useWalletExitBatch`](#useWalletExitBatch) to act on a plan: `exitBatch` previews and re-plans internally, so this hook is for a standalone preview screen rather than a required prerequisite step before calling `exitBatch`.

```ts
function useWalletExitPlan(): {
  plan(req: GetExitPlanRequest): Promise<GetExitPlanResult>;
  planPending: boolean;
  planError: Error | null;
  planData: GetExitPlanResult | null;
  resetPlan(): void;
};
```

- `plan(req)` `(req: GetExitPlanRequest) => Promise<GetExitPlanResult>`

  Previews funding for the given outpoints without moving funds. See getExitPlan on the wavelength-core reference.

Returns: `{ plan, planPending, planError, planData, resetPlan }`:

See [the mutation convention](#the-mutation-convention).

### useWalletSweep

function

Previews (`broadcast: false`) or broadcasts (`broadcast: true`) a sweep of the backing on-chain wallet, with hook-local sweepPending/sweepError/sweepData state. A 1:1 wrapper around [`WalletEngine.sweepWallet()`](/reference/wavelength-core/#WalletEngine). Call it with `broadcast: false` first to preview the fee and net amount, then again with `broadcast: true` once the user confirms; only the broadcasting call moves funds and kicks a background refresh.

```ts
function useWalletSweep(): {
  sweep(req: SweepWalletRequest): Promise<SweepWalletResult>;
  sweepPending: boolean;
  sweepError: Error | null;
  sweepData: SweepWalletResult | null;
  resetSweep(): void;
};
```

- `sweep(req)` `(req: SweepWalletRequest) => Promise<SweepWalletResult>`

  Previews or broadcasts the sweep, depending on req.broadcast. See sweepWallet on the wavelength-core reference.

Returns: `{ sweep, sweepPending, sweepError, sweepData, resetSweep }`:

See [the mutation convention](#the-mutation-convention).

### useWalletExitBatch

function

The orchestrator: starts a batch of exits across multiple outpoints, handling the funding-contention guards internally. Unlike the other mutation hooks, it also exposes `exitBatchEvents`, the batch’s progress events in order for the current or last run, so a UI can render a live per-outpoint timeline instead of waiting for the whole batch to settle.

> **exitBatch starts exits and moves money**
>
> Read the hazard callout on [`exitBatch`](/reference/wavelength-core/#exitBatch) in the wavelength-core reference: this hook’s `exitBatch` action resolves once every exit is **started**, not completed, and a unilateral exit keeps running for hours or days afterward.

```ts
function useWalletExitBatch(): {
  exitBatch(opts: ExitBatchOptions): Promise<ExitBatchResult>;
  exitBatchPending: boolean;
  exitBatchError: Error | null;
  exitBatchData: ExitBatchResult | null;
  exitBatchEvents: ExitBatchEvent[];
  resetExitBatch(): void;
};
```

- `exitBatch(opts)` `(opts: ExitBatchOptions) => Promise<ExitBatchResult>`

  Starts the batch. See ExitBatchOptions on the wavelength-core reference for the cooperative/unilateral discriminated union.

Returns: `{ exitBatch, exitBatchPending, exitBatchError, exitBatchData, exitBatchEvents, resetExitBatch }`:

The [mutation convention](#the-mutation-convention), plus exitBatchEvents: the ExitBatchEvent list for the current or last run, reset to empty each time exitBatch() is called or resetExitBatch() runs.

### useWalletExitStatus

function

Reads one exit’s status. Defaults to the cheap, coarse phase-only call; pass `{ detailed: true }` for recovery-tree progress, the CSV maturity countdown, and a fee breakdown, at the cost of a live round-trip. Fetches on mount and whenever `outpoint` or the options change.

```ts
function useWalletExitStatus(
  outpoint: string,
  opts?: { detailed?: boolean; pollMs?: number },
): {
  status: ExitStatusResult | null;
  statusPending: boolean;
  statusError: Error | null;
  refreshStatus(): Promise<ExitStatusResult>;
};
```

- `outpoint` `string`

  The VTXO outpoint whose exit status is read.

- `opts.detailed` `boolean`

  Optional. Requests the detailed fields; leave it false for a coarse, cheaper status.

- `opts.pollMs` `number`

  Optional. Polls at this interval, in milliseconds, while the component stays mounted. Polling is opt-in (omit it for a one-shot fetch); it keeps running with no visibility/focus gating (including in a backgrounded tab) and stops only on unmount, so there is no timer left running once the user navigates away.

Returns: `{ status, statusPending, statusError, refreshStatus }`:

`status` is null before the first load resolves. Unlike the mutation hooks above, there is no reset action: refetch on demand with refreshStatus(), or change outpoint/opts to refetch automatically.

### useWalletExits

function

Reads the wallet-wide in-progress exit portfolio. Fetches on mount and whenever wallet activity changes, so a completed exit clears from the summary without a manual refresh.

```ts
function useWalletExits(): {
  summary: ExitSummaryResult | null;
  summaryPending: boolean;
  summaryError: Error | null;
  refreshSummary(): Promise<ExitSummaryResult>;
};
```

Returns: `{ summary, summaryPending, summaryError, refreshSummary }`:

`summary` is null before the first load resolves. Like useWalletExitStatus, there is no reset action; call refreshSummary() to refetch on demand.

### useWalletList

function

Lists wallet activity, VTXOs, or on-chain outputs on demand, with hook-local listPending/listError/listData state. A 1:1 wrapper around [`WalletEngine.list()`](/reference/wavelength-core/#WalletEngine). Reach for it for an on-demand fetch, such as populating a VTXO picker before an exit; the always-fresh activity feed is already available from [`useWalletActivity()`](#useWalletActivity) without a manual fetch.

```ts
function useWalletList(): {
  list(req: ListRequest): Promise<ListResult>;
  listPending: boolean;
  listError: Error | null;
  listData: ListResult | null;
  resetList(): void;
};
```

- `list(req)` `(req: ListRequest) => Promise<ListResult>`

  Lists the requested view. See list on the wavelength-core reference.

Returns: `{ list, listPending, listError, listData, resetList }`:

See [the mutation convention](#the-mutation-convention), with one exception: `listData` keeps the previous successful result while a new `list()` call is pending and after a failed call (last-good semantics), instead of clearing.

## Passkeys

### useWalletPasskey

function

Drives a passkey ceremony and opens the wallet through the engine, refreshing engine state on success so `phase` advances automatically. The ceremony is injected, which keeps `wavelength-react` free of any transport dependency: in the browser, pass [`webPasskeyCeremony`](/reference/wavelength-web/#webPasskeyCeremony) from `wavelength-web`; the React Native transport supplies `createNativePasskeyCeremony` ([wavelength-react-native](/reference/wavelength-react-native/)). Creation and opening track separately (`create*`/`open*` fields below) because apps render them on different screens. Must be called within a `WavelengthProvider` subtree; throws otherwise.

```ts
function useWalletPasskey(ceremony: PasskeyCeremony): {
  supported: boolean | null;
  create(appName: string): Promise<PasskeyWalletOutcome>;
  createPending: boolean;
  createError: Error | null;
  resetCreate(): void;
  open(credentialId?: string): Promise<PasskeyWalletOutcome>;
  openPending: boolean;
  openError: Error | null;
  resetOpen(): void;
};
```

- `ceremony` [`PasskeyCeremony`](/reference/wavelength-core/#PasskeyCeremony)

  Platform ceremony implementation. In the browser, pass webPasskeyCeremony from wavelength-web.

* `supported` `boolean | null`

  Whether the environment supports passkey PRF. Starts null while ceremony.supportsPasskeyPrf() is in flight, then settles to true or false once it resolves; if that probe rejects, supported settles to false rather than throwing. Treat null as still-checking and gate passkey UI on it accordingly, not as a falsy unsupported state. The probe is memoized per ceremony instance, so warming it once at app boot means supported is usually already settled by the time a screen reads it.

* `create(appName)` `(appName: string) => Promise<PasskeyWalletOutcome>`

  Registers a passkey and creates the wallet from it. Follows the same throw-and-capture convention as the mutation hooks above: it both resolves/rejects and updates createPending/createError/reset via resetCreate.

* `createPending` `boolean`

  True while create() is in flight.

* `createError` `Error | null`

  The last error from create(), or null. A PasskeyCancelledError is never recorded here.

* `resetCreate()` `() => void`

  Clears createPending/createError back to idle.

* `open(credentialId?)` `(credentialId?: string) => Promise<PasskeyWalletOutcome>`

  Asserts a passkey (scoped to credentialId when provided, discoverable otherwise) and imports/unlocks the wallet.

* `openPending` `boolean`

  True while open() is in flight.

* `openError` `Error | null`

  The last error from open(), or null. A PasskeyCancelledError is never recorded here.

* `resetOpen()` `() => void`

  Clears openPending/openError back to idle.

> **A cancelled ceremony still rejects**
>
> `create()` and `open()` reject with errors when they fail; a `PasskeyCancelledError` (user dismissed the OS prompt) is rethrown but never recorded into `createError`/`openError`. Always `await`/`catch` these calls, or read `createError`/`openError` for a declarative render.

### PasskeyWalletOutcome

type

Pairs the daemon-side open result with the credential id used in the ceremony, so the app can persist it and scope future unlocks to the same passkey. Returned by both `create` and `open`.

```ts
type PasskeyWalletOutcome = {
  result: OpenWalletFromPasskeyResult;
  credentialId: string;
};
```

- `result` [`OpenWalletFromPasskeyResult`](/reference/wavelength-core/#OpenWalletFromPasskeyResult)

  The result returned by opening the wallet from the passkey. See OpenWalletFromPasskeyResult on the wavelength-core reference.

- `credentialId` `string`

  The credential id that produced the PRF output, for persistence and scoping future assertions.

### PasskeyCeremony

type

The per-platform contract `useWalletPasskey` drives. It is defined in `wavelength-core` but documented here since this package is its primary consumer; the browser implementation, `webPasskeyCeremony`, lives in [`wavelength-web`](/reference/wavelength-web/#webPasskeyCeremony). The React Native transport supplies `createNativePasskeyCeremony` ([wavelength-react-native](/reference/wavelength-react-native/)) as its implementation of the same contract.

```ts
type WalletKind = 'passkey' | 'password';

type PasskeyAssertion = {
  prfOutput: string;
  credentialId: string;
};

type PasskeyCeremony = {
  supportsPasskeyPrf(): Promise<boolean>;
  registerPasskeyWallet(appName: string): Promise<PasskeyAssertion>;
  assertPasskeyPrf(allowCredentialId?: string): Promise<PasskeyAssertion>;
};
```

- `WalletKind` `'passkey' | 'password'`

  Labels how a local wallet is unlocked.

- `supportsPasskeyPrf()` `() => Promise<boolean>`

  Resolves true when the platform supports passkey PRF.

- `registerPasskeyWallet(appName)` `(appName: string) => Promise<PasskeyAssertion>`

  Registers a new passkey and returns its assertion. appName becomes the WebAuthn relying-party name in the web implementation.

- `assertPasskeyPrf(allowCredentialId?)` `(allowCredentialId?: string) => Promise<PasskeyAssertion>`

  Asserts an existing passkey, optionally scoped to a credential id (discoverable when omitted).

- `PasskeyAssertion.prfOutput` `string`

  The PRF output (hex) shared with the Go SDK.

- `PasskeyAssertion.credentialId` `string`

  The credential id that produced the PRF output.

## Re-exported from wavelength-core

`@lightninglabs/wavelength-react` re-exports the complete `@lightninglabs/wavelength-core` surface. That includes `WavelengthClient`, `WalletEngine`, `createWalletEngine`, `FacadeMethod`, `ActivityStreamOptions`, `RuntimeConfig`, `WalletInfo`, `WalletStatus`, `Balance`, `Entry`, the complete activity/exit/send/list type families, all named nested response types, and all generated string-enum constants. `RuntimePhase`, `WalletState`, `RecoveryState`, `PasskeyCancelledError`, and `toError` are included too. `defaultConfig` comes from the transport packages (`@lightninglabs/wavelength-web` and `@lightninglabs/wavelength-react-native`). The core contract and enum constant families are listed on the [wavelength-core reference](/reference/wavelength-core/).

## See also

- [wavelength-core reference](/reference/wavelength-core/) for `WalletEngine`, `WavelengthClient`, `RuntimeConfig`, `WalletInfo`, `Balance`, `Entry`, `RuntimePhase`, and `WalletState`.
- [wavelength-web reference](/reference/wavelength-web/) for `createWebWalletEngine()` and `webPasskeyCeremony`, the browser transport and passkey ceremony used with this package.
- [wavelength-react-native reference](/reference/wavelength-react-native/) for `createNativeWalletEngine()` and `createNativePasskeyCeremony()`, the React Native transport and passkey ceremony used with this package.
