---
title: "wavelength-core"
description: "Cross-platform interfaces, shared types, and error codes that every Wavelength SDK platform target builds on."
canonical: https://wavelength.lightning.engineering/reference/wavelength-core/
---

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

# wavelength-core

Cross-platform interfaces, shared types, and error codes that every Wavelength SDK platform target builds on.

`@lightninglabs/wavelength-core` defines the portable wallet contract every SDK target builds on. It provides the typed client surface, shared wallet primitives, and error model without taking a dependency on the browser, React, or React Native.

At a glance

Typed contract

WavelengthClient, WalletEngine primitives, request and result shapes, errors, and events share one interface.

At a glance

Cross-platform core

wavelength-web implements this contract in the browser, while React and React Native bindings build on the same surface.

At a glance

Predictable responses

Daemon responses arrive as camelCase JavaScript values, with known optional values and arrays normalized for app code.

## Configuration

## networkDefaults

function

Returns the canonical public endpoint preset for a network in one transport’s flavor: REST gateway URLs for `'rest'` (the web transport), host:port gRPC addresses for `'grpc'` (native transports). This is the building block the transport packages’ `defaultConfig` helpers compose over; app code normally calls [wavelength-web’s](/reference/wavelength-web/#defaultConfig) or [wavelength-react-native’s](/reference/wavelength-react-native/#defaultConfig) `defaultConfig` instead.

Only the preset networks are accepted. `mainnet` and `regtest` have no preset: a `RuntimeConfig` for either is built by hand.

```ts
function networkDefaults(
  network: PresetNetwork,
  transport: ServerTransport,
): Partial<RuntimeConfig>
```

| Parameter   | Type                                                             | Description                                                                                   |
| ----------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `network`   | `PresetNetwork`                                                  | The Bitcoin network to look up; mainnet and regtest are excluded because they have no preset. |
| `transport` | [`ServerTransport`](/reference/wavelength-core/#ServerTransport) | The endpoint flavor the caller's transport dials: 'rest' or 'grpc'.                           |

Returns`Partial<RuntimeConfig>`

The preset config fields for that network and transport.

## DEBUG\_LEVELS

const

The standard daemon log verbosity levels, from most to least verbose. Exported for UIs that render a level picker; `debugLevel` itself stays a plain string because the daemon also accepts a per-subsystem list such as `'ROND=debug,info'`.

```ts
const DEBUG_LEVELS = [
  'trace', 'debug', 'info', 'warn', 'error', 'critical', 'off',
] as const;

type DebugLevel = (typeof DEBUG_LEVELS)[number];
```

## RuntimeConfig

type

Configuration passed to `WavelengthClient.start()`. For the common case, start from your transport package’s `defaultConfig(network)` and override only the fields you need.

```ts
type RuntimeConfig = {
  network?: Network;
  allowMainnet?: boolean;
  dataDir?: string;
  debugLevel?: string;
  arkServerAddress?: string;
  arkServerTlsCertPath?: string;
  arkServerInsecure?: boolean;
  walletType?: 'lwwallet' | 'btcwallet';
  walletEsploraUrl?: string;
  walletPasswordFile?: string;
  walletPollIntervalSeconds?: number;
  walletRecoveryWindow?: number;
  walletFeeUrl?: string;
  walletBlockHeadersSource?: string;
  walletFilterHeadersSource?: string;
  swapServerAddress?: string;
  swapServerTlsCertPath?: string;
  swapServerInsecure?: boolean;
  swapDatabaseFileName?: string;
  disableSwaps?: boolean;
  maxOperatorFeeSat?: number;
  signingWorkers?: number;
  bufferSize?: number;
};
```

The fields stay flat even when they apply to one embedded backend. For example, this `btcwallet` configuration uses only top-level `RuntimeConfig` fields:

```ts
const config: RuntimeConfig = {
  network: 'signet',
  walletType: 'btcwallet',
  walletFeeUrl: 'https://fees.example.com',
  walletBlockHeadersSource: 'neutrino',
  walletFilterHeadersSource: 'neutrino',
  walletRecoveryWindow: 250,
  maxOperatorFeeSat: 100,
  signingWorkers: 4,
  bufferSize: 64,
};
```

| Parameter                   | Type                                             | Description                                                                                                                                                           |
| --------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `network`                   | [`Network`](/reference/wavelength-core/#Network) | The Bitcoin network to run against. Use mainnet only together with allowMainnet.                                                                                      |
| `allowMainnet`              | `boolean`                                        | Must be true to run on mainnet. The SDK rejects a mainnet config without it before startup.                                                                           |
| `dataDir`                   | `string`                                         | Storage root for daemon and wallet state (an OPFS path in the browser). A daemon default is used when unset.                                                          |
| `debugLevel`                | `string`                                         | Daemon log verbosity. Accepts a standard DebugLevel or a per-subsystem expression such as 'ROND=debug,info'. Distinct from the web client's RPC-payload debug option. |
| `arkServerAddress`          | `string`                                         | Ark operator and mailbox endpoint. Use a REST URL on web and a host:port gRPC address on React Native.                                                                |
| `arkServerTlsCertPath`      | `string`                                         | Optional filesystem TLS certificate path for native transports. The web transport rejects it.                                                                         |
| `arkServerInsecure`         | `boolean`                                        | Disables TLS for the Ark endpoint. Use only for local development.                                                                                                    |
| `walletType`                | `'lwwallet' \| 'btcwallet'`                      | Embedded wallet backend. Default: lwwallet.                                                                                                                           |
| `walletEsploraUrl`          | `string`                                         | HTTP Esplora endpoint for lwwallet only, on both platforms.                                                                                                           |
| `walletPasswordFile`        | `string`                                         | Password file for lwwallet only.                                                                                                                                      |
| `walletPollIntervalSeconds` | `number`                                         | Chain polling interval for lwwallet only. Must be a nonnegative safe integer.                                                                                         |
| `walletRecoveryWindow`      | `number`                                         | Wallet address look-ahead window for either supported embedded backend. Must fit in uint32.                                                                           |
| `walletFeeUrl`              | `string`                                         | Fee estimator endpoint for btcwallet only.                                                                                                                            |
| `walletBlockHeadersSource`  | `string`                                         | Block-header source for btcwallet only.                                                                                                                               |
| `walletFilterHeadersSource` | `string`                                         | Compact-filter-header source for btcwallet only.                                                                                                                      |
| `swapServerAddress`         | `string`                                         | Swap endpoint. Use a REST URL on web and a host:port gRPC address on React Native.                                                                                    |
| `swapServerTlsCertPath`     | `string`                                         | Optional filesystem TLS certificate path for native transports. The web transport rejects it unless swaps are disabled.                                               |
| `swapServerInsecure`        | `boolean`                                        | Disables TLS for the swap endpoint. Use only for local development.                                                                                                   |
| `swapDatabaseFileName`      | `string`                                         | Daemon-owned SQLite file for swap state.                                                                                                                              |
| `disableSwaps`              | `boolean`                                        | Disables Lightning swaps and suppresses preset and override swap fields.                                                                                              |
| `maxOperatorFeeSat`         | `number`                                         | Maximum operator fee in satoshis. Must be a nonnegative safe integer.                                                                                                 |
| `signingWorkers`            | `number`                                         | Signing worker count. Must be a nonnegative safe integer.                                                                                                             |
| `bufferSize`                | `number`                                         | Runtime buffer size. Must be a nonnegative safe integer.                                                                                                              |

The SDK validates `RuntimeConfig` before it starts the daemon. It rejects backend-only fields used with the wrong `walletType`, invalid numeric values, mainnet without `allowMainnet: true`, and `arkServerTlsCertPath` on web. Web accepts `swapServerTlsCertPath` only when `disableSwaps: true`, which suppresses every swap field. `lwwallet` fields are `walletEsploraUrl`, `walletPasswordFile`, and `walletPollIntervalSeconds`. `btcwallet` fields are `walletFeeUrl`, `walletBlockHeadersSource`, and `walletFilterHeadersSource`.

LND and eager-round-join disable are intentionally unavailable through this mobile start contract. Most apps should use `defaultConfig()` from their transport package and override only the fields they need.

## Network

type

Selects the Bitcoin network the embedded daemon runs against. `PresetNetwork` narrows the union to the networks that carry a public endpoint preset (the domain of `networkDefaults` and the transports’ `defaultConfig`). mainnet and regtest are excluded: mainnet has no public deployment yet, and regtest’s local ports vary per development environment.

```ts
type Network = 'mainnet' | 'testnet' | 'testnet4' | 'signet' | 'regtest';
```

The transport packages’ `defaultConfig()` helpers draw from one canonical endpoint table per network, so the common case needs no URLs looked up. Toggle between the REST gateway URLs (web transport) and the gRPC host:port addresses (React Native transport):

RESTgRPC

signet

- arkServerAddress

  `https://signet.wavelength-rest.lightning.finance``signet.wavelength.lightning.finance:443`

- walletEsploraUrl

  `https://mempool-signet.testnet.lightningcluster.com/api`

- swapServerAddress

  `https://signet.swapd-rest.lightning.finance``swap.signet.wavelength.lightning.finance:443`

testnet

- arkServerAddress

  `https://test.wavelength-rest.lightning.finance``test.wavelength.lightning.finance:443`

- walletEsploraUrl

  `https://mempool-testnet3.testnet.lightningcluster.com/api`

- swapServerAddress

  `https://test.swapd-rest.lightning.finance``swap.test.wavelength.lightning.finance:443`

mainnet

No public preset - build the RuntimeConfig by hand with your own arkServerAddress, walletEsploraUrl, swapServerAddress, and allowMainnet.

> **mainnet has no public preset**
>
> mainnet is not a `PresetNetwork`, so there is no `defaultConfig` for it. There is no canonical public gateway for mainnet yet, so build the `RuntimeConfig` by hand: supply your own `arkServerAddress`, `walletEsploraUrl`, and `swapServerAddress` (or `disableSwaps`) and pass `allowMainnet: true`, or `start()` will refuse to run.

## ServerTransport

type

The wire protocol used by a transport to connect to the Ark and swap servers. Browser transports use `rest`; native transports use `grpc`.

```ts
type ServerTransport = 'rest' | 'grpc';
```

## MobileConfig

type

The flat configuration shape passed to the embedded mobile facade. Application code normally supplies [`RuntimeConfig`](#RuntimeConfig) instead. This internal shape is shown for transport debugging and is not exported from the core package.

```ts
type MobileConfig = {
  data_dir?: string;
  network?: string;
  allow_mainnet?: boolean;
  debug_level?: string;
  wallet_type?: 'lwwallet' | 'btcwallet';
  wallet_esplora_url?: string;
  wallet_password_file?: string;
  wallet_poll_interval_seconds?: number;
  wallet_recovery_window?: number;
  wallet_fee_url?: string;
  wallet_block_headers_source?: string;
  wallet_filter_headers_source?: string;
  server_address?: string;
  server_tls_cert_path?: string;
  server_transport?: ServerTransport;
  server_insecure?: boolean;
  swap_server_address?: string;
  swap_server_tls_cert_path?: string;
  swap_server_transport?: ServerTransport;
  swap_server_insecure?: boolean;
  swap_database_file_name?: string;
  max_operator_fee_sat?: number;
  signing_workers?: number;
  buffer_size?: number;
};
```

Calling `client.callFacade('start', mobileConfig)` sends this lower-level shape directly to the daemon and bypasses public `RuntimeConfig` validation. App code should call `client.start(config)` instead.

## Client lifecycle

## WavelengthClient

type

The typed RPC surface every transport implements. Create a client with [`createWebClient()`](/reference/wavelength-web/) from wavelength-web or `createNativeClient()` from [wavelength-react-native](/reference/wavelength-react-native/), call `start(config)`, then use the wallet methods documented in the sections below.

```ts
interface WavelengthClient {
  ready(): Promise<void>;
  start(config: RuntimeConfig): Promise<WalletInfo>;
  stop(): Promise<void>;
  getInfo(): Promise<WalletInfo>;
  status(): Promise<WalletStatus>;
  balance(): Promise<Balance>;
  createWallet(req: CreateWalletRequest): Promise<CreateWalletResult>;
  unlockWallet(req: UnlockWalletRequest): Promise<UnlockWalletResult>;
  openWalletFromPasskey(req: OpenWalletFromPasskeyRequest): Promise<OpenWalletFromPasskeyResult>;
  deposit(req?: DepositRequest): Promise<DepositResult>;
  receive(req: ReceiveRequest): Promise<ReceiveResult>;
  prepareSend(req: SendRequest): Promise<PrepareSendResult>;
  sendPrepared(prepared: PrepareSendResult): Promise<SendResult>;
  send(req: SendRequest): Promise<SendResult>;
  list(req?: ListRequest): Promise<ListResult>;
  exit(req: ExitRequest): Promise<ExitResult>;
  exitStatus(req: ExitStatusRequest): Promise<ExitStatusResult>;
  exitSummary(req?: ExitSummaryRequest): Promise<ExitSummaryResult>;
  getExitPlan(req: GetExitPlanRequest): Promise<GetExitPlanResult>;
  sweepWallet(req: SweepWalletRequest): Promise<SweepWalletResult>;
  callFacade<T = unknown>(method: FacadeMethod, params?: unknown): Promise<T>;
  isRunning(): Promise<boolean>;
  subscribe(listener: WavelengthListener): () => void;
  startActivity(opts?: ActivityStreamOptions): Promise<void>;
  stopActivity(): void;
  dispose(): void;
}
```

**Call order.** A client’s methods are only meaningful in this order: await `ready()` once, then `start(config)` once, then any of the wallet operations (any number of times, in any order appropriate to your app), then `stop()` when you are done running the daemon, then `dispose()` to release the client’s own resources. `isRunning()` is the exception: it can be called before startup or after shutdown to inspect the daemon process state. `dispose()` is terminal: build a new client to start again.

## ready

function

Resolves once the runtime assets (the wasm daemon and its supporting files) are loaded and the client is otherwise usable. Always await this before `start()`.

```ts
ready(): Promise<void>
```

Returns`Promise<void>`

Resolves when the client is ready to `start()`. Rejects with a `WavelengthError` (code `asset_load_failed`) if the runtime assets fail to load.

## start

function

Starts the embedded daemon with the given config and resolves with its initial [`WalletInfo`](#WalletInfo).

```ts
start(config: RuntimeConfig): Promise<WalletInfo>
```

| Parameter | Type                                                         | Description                                                                                                                           |
| --------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `config`  | [`RuntimeConfig`](/reference/wavelength-core/#RuntimeConfig) | The runtime configuration to start the daemon with. Build it with your transport package's defaultConfig(network) plus any overrides. |

Returns`Promise<WalletInfo>`

The daemon’s info immediately after startup, reflecting whatever wallet state already exists on disk (none, locked, or ready).

## stop

function

Stops the embedded daemon. The client instance itself remains usable afterward: call `start()` again to restart the daemon without constructing a new client. Use `dispose()` instead when you are done with the client entirely, since it also releases the client’s own resources (subscriptions, the activity stream, and, for the worker transport, the underlying Worker).

```ts
stop(): Promise<void>
```

Returns`Promise<void>`

Resolves once the daemon has stopped.

## dispose

function

Releases the client’s resources and unsubscribes all listeners: it closes the activity stream opened by [`startActivity()`](#startActivity) and, for the worker transport, terminates the underlying Worker. The client is unusable afterward; construct a new one to start again.

```ts
dispose(): void
```

Returns`void`

Nothing; the client is torn down synchronously.

## Wallet engine

`WalletEngine` is the headless wallet orchestrator every framework binding is built on: it owns the lifecycle phase machine, the state snapshot (`phase`, `info`, `balance`, `activity`, `recovery`, `logs`), and the background processes that keep them fresh. Build one over any transport with [`createWalletEngine()`](#createWalletEngine), or reach for a transport’s own factory (`createWebWalletEngine()` from [wavelength-web](/reference/wavelength-web/), `createNativeWalletEngine()` from [wavelength-react-native](/reference/wavelength-react-native/)), which builds the client for you. Pass the engine to `WavelengthProvider` from [wavelength-react](/reference/wavelength-react/), or drive it directly: `getSnapshot()`/`subscribe()` work the same for a vanilla consumer as for a framework binding.

## createWalletEngine

function

Creates a `WalletEngine` over any transport client.

```ts
function createWalletEngine(options: WalletEngineOptions): WalletEngine
```

| Parameter | Type                                                                     | Description                                                      |
| --------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| `options` | [`WalletEngineOptions`](/reference/wavelength-core/#WalletEngineOptions) | The client to drive, plus optional default config and autoStart. |

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

A live engine. It calls `client.ready()` immediately; `getSnapshot().phase` moves from `'loading'` to `'runtimeReady'` once that resolves (and, when `autoStart` is set, `start()` follows automatically).

**`WalletEngineOptions`**

A discriminated union: the types require a config when autoStart is enabled, so `autoStart: true` without `config` is a compile error.

```ts
type WalletEngineOptions =
  | { client: WavelengthClient; config: RuntimeConfig; autoStart: true }
  | { client: WavelengthClient; config?: RuntimeConfig; autoStart?: false };
```

| Parameter   | Type                                                               | Description                                                                                                                                                          |
| ----------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client`    | [`WavelengthClient`](/reference/wavelength-core/#WavelengthClient) | The transport client the engine drives.                                                                                                                              |
| `config`    | [`RuntimeConfig`](/reference/wavelength-core/#RuntimeConfig)       | Required when autoStart is true. Default runtime config used by autoStart and by start() when called with no argument.                                               |
| `autoStart` | `true \| false`                                                    | Optional. Start the runtime automatically once it is ready. Setting it to true requires config; start() still throws if later called with no argument and no config. |

**`DistributiveOmit`**

An advanced utility type used to omit a property from each member of a discriminated union independently. It is exported for transport and binding implementers; application code rarely needs it directly.

```ts
type DistributiveOmit<T, K extends PropertyKey> =
  T extends unknown ? Omit<T, K> : never;
```

## WalletEngine

type

The engine interface. Every method mirrors the matching `WavelengthClient` method plus engine bookkeeping: refetching info, kicking a background refresh, or advancing the phase machine.

```ts
interface WalletEngine {
  readonly client: WavelengthClient;
  getSnapshot(): WalletSnapshot;
  subscribe(listener: () => void): () => void;
  start(config?: RuntimeConfig): Promise<WalletInfo>;
  stop(): Promise<void>;
  refresh(): Promise<void>;
  createWallet(req: CreateWalletRequest): Promise<CreateWalletResult>;
  restoreWallet(req: RestoreWalletRequest): Promise<WalletInfo>;
  acknowledgeRecovery(): void;
  unlockWallet(req: UnlockWalletRequest): Promise<UnlockWalletResult>;
  openWalletFromPasskey(req: OpenWalletFromPasskeyRequest): Promise<OpenWalletFromPasskeyResult>;
  deposit(req?: DepositRequest): Promise<DepositResult>;
  receive(req: ReceiveRequest): Promise<ReceiveResult>;
  prepareSend(req: SendRequest): Promise<PrepareSendResult>;
  sendPrepared(prepared: PrepareSendResult): Promise<SendResult>;
  send(req: SendRequest): Promise<SendResult>;
  exit(req: ExitRequest): Promise<ExitResult>;
  exitStatus(req: ExitStatusRequest): Promise<ExitStatusResult>;
  exitSummary(req?: ExitSummaryRequest): Promise<ExitSummaryResult>;
  getExitPlan(req: GetExitPlanRequest): Promise<GetExitPlanResult>;
  sweepWallet(req: SweepWalletRequest): Promise<SweepWalletResult>;
  exitBatch(opts: ExitBatchOptions & {
    signal?: AbortSignal;
    onEvent?: (event: ExitBatchEvent) => void;
  }): Promise<ExitBatchResult>;
  list(req: ListRequest): Promise<ListResult>;
  clearLogs(): void;
  dispose(): void;
}
```

| Parameter                    | Type                                                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client`                     | [`WavelengthClient`](/reference/wavelength-core/#WavelengthClient)             | The underlying transport client, as an escape hatch.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `getSnapshot()`              | `() => WalletSnapshot`                                                         | The current immutable state snapshot; see WalletSnapshot below.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `subscribe(listener)`        | `(listener: () => void) => () => void`                                         | Subscribes to snapshot changes; returns the unsubscribe function. Framework bindings call this via useSyncExternalStore.                                                                                                                                                                                                                                                                                                                                                |
| `start(config?)`             | `(config?: RuntimeConfig) => Promise<WalletInfo>`                              | Starts the runtime. Falls back to the engine's configured config when called without an argument; throws if neither exists. A failure moves phase to 'error' and rejects. On success it best-effort calls refresh() (a locked or empty wallet can fail balance/list until bootstrap; that failure is swallowed).                                                                                                                                                        |
| `stop()`                     | `() => Promise<void>`                                                          | Stops the runtime and clears the in-memory snapshot (info/balance/activity reset to null/null/\[]); persisted wallet data is untouched. A failure moves phase to 'error'.                                                                                                                                                                                                                                                                                               |
| `refresh()`                  | `() => Promise<void>`                                                          | Re-fetches info, balance, and activity concurrently.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `createWallet(req)`          | `(req: CreateWalletRequest) => Promise<CreateWalletResult>`                    | Creates a new wallet, refetches info, and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                                                   |
| `restoreWallet(req)`         | `(req: RestoreWalletRequest) => Promise<WalletInfo>`                           | Restores a wallet from req.mnemonic. Resolves as soon as the restored wallet is usable; the optional server-assisted recovery scan (req.recoverState) continues in the background, observed through snapshot.recovery. Rejects only when the restore fails before the wallet came up; if the scan itself fails after the wallet is usable, the promise still resolves and the failure surfaces as recovery.status === 'failed' instead. See RestoreWalletRequest below. |
| `acknowledgeRecovery()`      | `() => void`                                                                   | Resets snapshot.recovery to { status: 'idle' } (e.g. after dismissing a banner).                                                                                                                                                                                                                                                                                                                                                                                        |
| `unlockWallet(req)`          | `(req: UnlockWalletRequest) => Promise<UnlockWalletResult>`                    | Unlocks an existing wallet, refetches info, and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                                             |
| `openWalletFromPasskey(req)` | `(req: OpenWalletFromPasskeyRequest) => Promise<OpenWalletFromPasskeyResult>`  | Opens the wallet from a passkey PRF output, refetches info, and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                             |
| `deposit(req?)`              | `(req?: DepositRequest) => Promise<DepositResult>`                             | Requests an on-chain deposit address and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                                                    |
| `receive(req)`               | `(req: ReceiveRequest) => Promise<ReceiveResult>`                              | Requests a Lightning receive and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                                                            |
| `prepareSend(req)`           | `(req: SendRequest) => Promise<PrepareSendResult>`                             | Quotes a payment without dispatching it. No refresh: a quote moves no money.                                                                                                                                                                                                                                                                                                                                                                                            |
| `sendPrepared(prepared)`     | `(prepared: PrepareSendResult) => Promise<SendResult>`                         | Dispatches a payment quoted by prepareSend and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                                              |
| `send(req)`                  | `(req: SendRequest) => Promise<SendResult>`                                    | Sends a payment and kicks a background refresh.                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `exit(req)`                  | `(req: ExitRequest) => Promise<ExitResult>`                                    | Starts a single exit (cooperative or unilateral) for one outpoint and kicks a background refresh. See exit below.                                                                                                                                                                                                                                                                                                                                                       |
| `exitStatus(req)`            | `(req: ExitStatusRequest) => Promise<ExitStatusResult>`                        | Queries the status of an exit job. Read-only: it moves no money, so it does not refresh. See exitStatus below.                                                                                                                                                                                                                                                                                                                                                          |
| `exitSummary(req?)`          | `(req?: ExitSummaryRequest) => Promise<ExitSummaryResult>`                     | Summarizes all in-progress exits. Read-only; does not refresh. See exitSummary below.                                                                                                                                                                                                                                                                                                                                                                                   |
| `getExitPlan(req)`           | `(req: GetExitPlanRequest) => Promise<GetExitPlanResult>`                      | Previews unilateral-exit readiness and funding without moving funds. Read-only; does not refresh. See getExitPlan below.                                                                                                                                                                                                                                                                                                                                                |
| `sweepWallet(req)`           | `(req: SweepWalletRequest) => Promise<SweepWalletResult>`                      | Previews (req.broadcast: false) or broadcasts (req.broadcast: true) a sweep of the backing on-chain wallet. Refreshes only when broadcasting, since a preview moves no money. See sweepWallet below.                                                                                                                                                                                                                                                                    |
| `exitBatch(opts)`            | `(opts: ExitBatchOptions & { signal?, onEvent? }) => Promise<ExitBatchResult>` | Starts a batch of exits, kicking a background refresh after each one starts. Resolves once every exit is started, not completed. Takes the same opts as the standalone exitBatch() below, minus client, since the engine already owns one. See exitBatch below.                                                                                                                                                                                                         |
| `list(req)`                  | `(req: ListRequest) => Promise<ListResult>`                                    | Lists wallet activity, VTXOs, or on-chain outputs. Read-only; does not refresh. See list below.                                                                                                                                                                                                                                                                                                                                                                         |
| `clearLogs()`                | `() => void`                                                                   | Clears the buffered log tail.                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `dispose()`                  | `() => void`                                                                   | Tears down subscriptions, polls, and streams. The engine is done after this; build a new one to start again.                                                                                                                                                                                                                                                                                                                                                            |

> **Background processes the engine owns**
>
> The engine runs several processes automatically, keyed off `phase`, so hosts never reimplement them:
>
> - **Activity-stream auto-refresh**: while `phase` is `'ready'`, the engine opens the transport’s activity stream and, on each event, runs a bounded settle-reconcile: an immediate `refresh()` followed by up to three follow-up re-reads (at 750ms, 1500ms, and 3000ms) that stop early once the balance has moved off its pre-event baseline and then held steady across two reads. This covers the daemon reporting an entry settled a beat before `balance()` reflects the new funds.
> - **Activity-stream recovery**: terminal `activityStream` events trigger a `list()` reconciliation, then the engine retries from the last safe numeric activity cursor with bounded exponential backoff. The cursor resets when the runtime stops or restarts. Replayed events trigger the same idempotent snapshot refresh instead of being appended directly, so the engine provides eventual snapshot consistency after a disconnect. The current web and native bridges do not expose structured gap cursor or reason details.
> - **Sync auto-poll**: while `phase` is `'syncing'`, the engine calls `refresh()` every 2000ms until the phase leaves `'syncing'`. After 5 consecutive failures it stops polling and escalates to `phase: 'error'` instead of polling forever.
> - **Restore readiness poll**: while `phase` is `'restoring'` (any `restoreWallet()` in flight; when the request sets `recoverState: true` the recovery scan is additionally tracked through `snapshot.recovery`), the engine polls `getInfo()` every 1500ms until the wallet reports ready, then settles the `restoreWallet()` promise and kicks a refresh.
> - **Background-refresh failure budget**: any refresh kicked after a mutation (create/unlock/restore/deposit/receive/send) or by a poll above shares one consecutive-failure counter. At 5 consecutive failures the engine sets `snapshot.error` and escalates `phase` to `'error'`, so a dead daemon cannot hide behind a healthy-looking ready wallet.
> - **Unsolicited `stopped` transition**: a `runtimeStopped` client event, whether from a clean `stop()` or a worker crash/fatal surfaced by the transport, moves `phase` to `'stopped'` and wipes `info`/`balance`/`activity` to `null`/`null`/`[]`, even if the host never called `stop()` itself.

## WalletSnapshot

type

The engine’s immutable state snapshot, returned by [`getSnapshot()`](#WalletEngine) and delivered to [`subscribe()`](#WalletEngine) listeners. A new object per change; refresh fetches that changed nothing keep the previous field references, so consumers can cheaply compare slices with `Object.is`.

```ts
type WalletSnapshot = {
phase: RuntimePhase;
error: Error | null;
info: WalletInfo | null;
balance: Balance | null;
activity: Entry[];
recovery: RecoveryState;
logs: WavelengthLogPayload[];
};
```

| Parameter  | Type                                                         | Description                                                                       |
| ---------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| `phase`    | [`RuntimePhase`](/reference/wavelength-core/#RuntimePhase)   | The current runtime/wallet lifecycle phase.                                       |
| `error`    | `Error \| null`                                              | The last fatal runtime-level error, or null.                                      |
| `info`     | `WalletInfo \| null`                                         | The most recent complete wallet info, or null before the runtime reports it.      |
| `balance`  | `Balance \| null`                                            | The most recent wallet balance, or null before it is known.                       |
| `activity` | `Entry[]`                                                    | The most recent activity entries, newest-first as returned by the daemon.         |
| `recovery` | [`RecoveryState`](/reference/wavelength-core/#RecoveryState) | The background recovery status set by restoreWallet(); see RecoveryState below.   |
| `logs`     | `WavelengthLogPayload[]`                                     | A bounded tail (up to 200 entries) of 'log' events from the runtime, newest last. |

## RecoveryState

type

The state of a background wallet recovery started by `restoreWallet()`, a discriminated union keyed on `status`.

```ts
type RecoveryState =
| { status: 'idle' }
| { status: 'restoring' }
| { status: 'done'; result: CreateWalletResult }
| { status: 'failed'; error: Error; walletUsable: boolean };
```

| Parameter                                   | Type      | Description                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `{ status: 'idle' }`                        | `variant` | No tracked restore in flight, and none has run since the last acknowledgeRecovery() (or ever).                                                                                                                                                                                                                                                                                 |
| `{ status: 'restoring' }`                   | `variant` | While the daemon's server-assisted scan runs. The wallet is already usable at this point; restoreWallet()'s promise has typically already resolved.                                                                                                                                                                                                                            |
| `{ status: 'done', result }`                | `variant` | Once the scan completes successfully. result carries the same CreateWalletResult recovery counters (recoveredVTXOs, recoveredBoardingUTXOs, and so on) documented under CreateWalletResult above.                                                                                                                                                                              |
| `{ status: 'failed', error, walletUsable }` | `variant` | walletUsable is true when the background scan errored on an already-usable wallet (its state may just be incomplete), and false when the restore itself failed before the wallet came up at all. This also covers an untracked restore (a restoreWallet() call whose promise was not awaited, or whose caller unmounted): the failure still lands here, surviving the unmount. |

Read it to drive a “restoring your balance and history” banner while the wallet is already usable (`walletUsable: true`), or a restore-failed message on the onboarding screen when the restore never got that far (`walletUsable: false`), and call `acknowledgeRecovery()` to dismiss it back to `'idle'`.

## RestoreWalletRequest

type

Parameters for [`WalletEngine.restoreWallet()`](#WalletEngine): everything [`CreateWalletRequest`](#createWallet) accepts, with `mnemonic` promoted from optional to required, since a restore is meaningless without one.

```ts
type RestoreWalletRequest = CreateWalletRequest & {
  mnemonic: string[];
};
```

| Parameter        | Type       | Description                                                                                                                                                                                                                     |
| ---------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mnemonic`       | `string[]` | The recovery phrase to restore from. Required (unlike CreateWalletRequest.mnemonic, which is optional).                                                                                                                         |
| `password`       | `string`   | The plain password the client base64-encodes into the daemon's byte field.                                                                                                                                                      |
| `seedPassphrase` | `string`   | Optional. A BIP-39 passphrase applied on top of the mnemonic.                                                                                                                                                                   |
| `recoverState`   | `boolean`  | Optional. Opt into server-assisted recovery, tracked through snapshot.recovery. Set this for a restore so funds and activity come back; see CreateWalletRequest.recoverState above for the full description. Defaults to false. |
| `recoveryWindow` | `number`   | Optional. The per-key-family address look-ahead used during recovery. Only meaningful when recoverState is true.                                                                                                                |

## Wallet setup and authentication

## createWallet

function

Creates a new wallet from the given request: generates (or imports) a mnemonic, enciphers it with `password`, and returns the seed words for backup display.

```ts
createWallet(req: CreateWalletRequest): Promise<CreateWalletResult>
```

| Parameter | Type                                                                     | Description                                        |
| --------- | ------------------------------------------------------------------------ | -------------------------------------------------- |
| `req`     | [`CreateWalletRequest`](/reference/wavelength-core/#CreateWalletRequest) | Parameters for creating (or importing) the wallet. |

Returns`Promise<CreateWalletResult>`

The generated (or imported) mnemonic, the daemon identity, and recovery counters.

**`CreateWalletRequest`**

```ts
type CreateWalletRequest = {
  password: string;
  mnemonic?: string[];
  seedPassphrase?: string;
  recoverState?: boolean;
  recoveryWindow?: number;
};
```

| Parameter        | Type       | Description                                                                                                                                                                                                                                            |
| ---------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `password`       | `string`   | The plain password the client base64-encodes into the daemon's byte field.                                                                                                                                                                             |
| `mnemonic`       | `string[]` | Optional. An existing mnemonic to restore from; a fresh one is generated when omitted.                                                                                                                                                                 |
| `seedPassphrase` | `string`   | Optional. A BIP-39 passphrase applied on top of the mnemonic.                                                                                                                                                                                          |
| `recoverState`   | `boolean`  | Optional. Opt into server-assisted recovery: rebuild wallet state (boarding UTXOs, VTXOs, receive history) from the seed by querying the operator's indexer. Set it when restoring from a mnemonic so funds and activity come back. Defaults to false. |
| `recoveryWindow` | `number`   | Optional. The per-key-family address look-ahead used during recovery. Only meaningful when recoverState is true; omit to let the daemon resolve its own default.                                                                                       |

**`CreateWalletResult`**

```ts
type CreateWalletResult = {
  mnemonic: string[];
  encipheredSeed: string;
  identityPubKey: string;
  recoveryRan: boolean;
  recoveredBoardingAddresses: number;
  recoveredBoardingUTXOs: number;
  recoveredVTXOs: number;
  recoveredOORReceiveScripts: number;
  recoveredOORRecipientEvents: number;
};
```

| Parameter                     | Type       | Description                                                                                           |
| ----------------------------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| `mnemonic`                    | `string[]` | The seed words. Display this to the user for backup; it is not recoverable from the daemon afterward. |
| `encipheredSeed`              | `string`   | The password-enciphered seed, as stored by the daemon.                                                |
| `identityPubKey`              | `string`   | The wallet's identity public key.                                                                     |
| `recoveryRan`                 | `boolean`  | True when mnemonic was supplied and the daemon ran chain recovery to rediscover funds.                |
| `recoveredBoardingAddresses`  | `number`   | Count of boarding addresses recovered. Only meaningful when recoveryRan is true.                      |
| `recoveredBoardingUTXOs`      | `number`   | Count of boarding UTXOs recovered.                                                                    |
| `recoveredVTXOs`              | `number`   | Count of VTXOs recovered.                                                                             |
| `recoveredOORReceiveScripts`  | `number`   | Count of out-of-round receive scripts recovered.                                                      |
| `recoveredOORRecipientEvents` | `number`   | Count of out-of-round recipient events recovered.                                                     |

## unlockWallet

function

Unlocks an existing wallet with the given password.

```ts
unlockWallet(req: UnlockWalletRequest): Promise<UnlockWalletResult>
```

| Parameter | Type                                                                     | Description                  |
| --------- | ------------------------------------------------------------------------ | ---------------------------- |
| `req`     | [`UnlockWalletRequest`](/reference/wavelength-core/#UnlockWalletRequest) | The password to unlock with. |

Returns`Promise<UnlockWalletResult>`

The daemon identity after unlock.

**`UnlockWalletRequest`**

```ts
type UnlockWalletRequest = {
  password: string;
};
```

| Parameter  | Type     | Description                                                                |
| ---------- | -------- | -------------------------------------------------------------------------- |
| `password` | `string` | The plain password the client base64-encodes into the daemon's byte field. |

**`UnlockWalletResult`**

```ts
type UnlockWalletResult = {
  identityPubKey: string;
};
```

| Parameter        | Type     | Description                       |
| ---------------- | -------- | --------------------------------- |
| `identityPubKey` | `string` | The wallet's identity public key. |

## openWalletFromPasskey

function

Opens a wallet from a passkey assertion: derives a wallet from the PRF output of a [`PasskeyCeremony`](#PasskeyCeremony) ceremony, creating one on first use per device or unlocking the existing one thereafter.

```ts
openWalletFromPasskey(
  req: OpenWalletFromPasskeyRequest,
): Promise<OpenWalletFromPasskeyResult>
```

| Parameter | Type                                                                                       | Description                                       |
| --------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------- |
| `req`     | [`OpenWalletFromPasskeyRequest`](/reference/wavelength-core/#OpenWalletFromPasskeyRequest) | The passkey PRF output to derive the wallet from. |

Returns`Promise<OpenWalletFromPasskeyResult>`

Whether a wallet was freshly created from the derived seed, plus the mnemonic (on import only) and the daemon identity.

**`OpenWalletFromPasskeyRequest`**

```ts
type OpenWalletFromPasskeyRequest = {
  prfOutput: string;
};
```

| Parameter   | Type     | Description                                                                   |
| ----------- | -------- | ----------------------------------------------------------------------------- |
| `prfOutput` | `string` | The PRF output (hex) derived from the passkey ceremony. See PasskeyAssertion. |

**`OpenWalletFromPasskeyResult`**

```ts
type OpenWalletFromPasskeyResult = {
  imported: boolean;
  mnemonic: string[];
  identityPubKey: string;
};
```

| Parameter        | Type       | Description                                                                                                                                                         |
| ---------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `imported`       | `boolean`  | true when a new local wallet was created from the derived seed (a fresh device that has never seen this passkey); false when an existing local wallet was unlocked. |
| `mnemonic`       | `string[]` | The seed words. Populated only when imported is true, for backup display.                                                                                           |
| `identityPubKey` | `string`   | The wallet's identity public key.                                                                                                                                   |

## Reading wallet state

**When to use each.** `getInfo()` is the richest snapshot (daemon version, network, block height, and wallet lifecycle state) and is what `start()` also returns; reach for it when you need `walletState` or build metadata. `status()` is a lighter operational check (ready/unlocked/pending count) that also embeds the balance, useful for a quick health probe. `balance()` returns only the `Balance` you would find nested in `status().balance`; call it directly when that is all you need. `isRunning()` reports only whether the embedded daemon process is running.

The typed methods are the preferred way to read facade-level scalar values:

```ts
const confirmedBalanceSat = (await client.balance()).confirmedSat;
const pendingInboundSat = (await client.balance()).pendingInSat;
const walletReady = (await client.getInfo()).walletReady;
const running = await client.isRunning();
```

The `confirmedBalanceSat`, `pendingInboundSat`, `walletReady`, and `isRunning` facade verbs also remain available through [`callFacade()`](#callFacade) for portable low-level integrations.

## getInfo

function

Returns the current normalized wallet info.

```ts
getInfo(): Promise<WalletInfo>
```

Returns`Promise<WalletInfo>`

The current wallet and daemon info.

## status

function

Returns the daemon’s runtime status snapshot.

```ts
status(): Promise<WalletStatus>
```

Returns`Promise<WalletStatus>`

The current readiness, lock, network, balance, and pending-activity snapshot.

## balance

function

Returns the current wallet balance.

```ts
balance(): Promise<Balance>
```

Returns`Promise<Balance>`

The current confirmed and pending balances, in satoshis.

## isRunning

function

Reports whether the embedded daemon is running. This does not report wallet readiness; use [`getInfo()`](#getInfo) when you need `walletReady`.

```ts
isRunning(): Promise<boolean>
```

Returns`Promise<boolean>`

`true` while the embedded daemon process is running.

## WalletInfo

type

Wallet and daemon info returned by [`getInfo()`](#getInfo) and [`start()`](#start).

```ts
type WalletInfo = {
  version: string;
  commit: string;
  network: string;
  blockHeight: number;
  serverConnected: boolean;
  walletType: string;
  identityPubKey: string;
  walletState: WalletState;
  walletReady: boolean;
  serverInfo?: ServerInfo;
};
```

| Parameter         | Type                                                     | Description                                                                                                                                                                 |
| ----------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `version`         | `string`                                                 | The daemon version string.                                                                                                                                                  |
| `commit`          | `string`                                                 | The daemon build commit hash.                                                                                                                                               |
| `network`         | `string`                                                 | The Bitcoin network the daemon is running against.                                                                                                                          |
| `blockHeight`     | `number`                                                 | The current chain tip height the wallet has synced to.                                                                                                                      |
| `serverConnected` | `boolean`                                                | Whether the daemon's connection to the Ark server is currently up.                                                                                                          |
| `walletType`      | `string`                                                 | The backing wallet implementation in use.                                                                                                                                   |
| `identityPubKey`  | `string`                                                 | The wallet's identity public key.                                                                                                                                           |
| `walletState`     | [`WalletState`](/reference/wavelength-core/#WalletState) | The wallet lifecycle state, normalized to the SDK string union.                                                                                                             |
| `walletReady`     | `boolean`                                                | True iff the wallet is unlocked and ready (mirrors the daemon's Info.WalletReady() method); backfilled by normalizeInfo() since the daemon JSON does not carry it directly. |
| `serverInfo`      | [`ServerInfo`](/reference/wavelength-core/#ServerInfo)   | Operator policy hints, when the daemon has learned them from the Ark server; see ServerInfo below. Optional: absent until the daemon has cached the operator terms.         |

## ServerInfo

type

Operator policy hints surfaced on [`WalletInfo.serverInfo`](#WalletInfo). The daemon learns these from its cached operator terms at bootstrap and on later terms refreshes.

```ts
type ServerInfo = {
  freeRefreshWindowBlocks: number;
};
```

| Parameter                 | Type     | Description                                                                                                                                                        |
| ------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `freeRefreshWindowBlocks` | `number` | The late-lifetime window, in blocks before VTXO expiry, in which a pure refresh receives an operator fee waiver. 0 means the operator advertises no waiver window. |

## WalletStatus

type

Runtime status snapshot returned by [`status()`](#status).

```ts
type WalletStatus = {
  ready: boolean;
  unlocked: boolean;
  network: string;
  balance: Balance;
  pendingCount: number;
};
```

| Parameter      | Type                                             | Description                                                      |
| -------------- | ------------------------------------------------ | ---------------------------------------------------------------- |
| `ready`        | `boolean`                                        | Whether the wallet is unlocked and fully usable.                 |
| `unlocked`     | `boolean`                                        | Whether the wallet is currently unlocked (may still be syncing). |
| `network`      | `string`                                         | The Bitcoin network the daemon is running against.               |
| `balance`      | [`Balance`](/reference/wavelength-core/#Balance) | The current wallet balance; see Balance below.                   |
| `pendingCount` | `number`                                         | The number of activity entries currently pending.                |

## Balance

type

Wallet-level balance returned by [`balance()`](#balance) and embedded in [`WalletStatus.balance`](#WalletStatus). All amounts are in satoshis.

```ts
type Balance = {
  confirmedSat: number;
  pendingInSat: number;
  pendingOutSat: number;
};
```

| Parameter       | Type     | Description                       |
| --------------- | -------- | --------------------------------- |
| `confirmedSat`  | `number` | Spendable VTXO balance.           |
| `pendingInSat`  | `number` | Inbound amount not yet confirmed. |
| `pendingOutSat` | `number` | Outbound amount in flight.        |

## Deposits and receiving

## deposit

function

Generates an on-chain deposit (boarding) address.

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

| Parameter | Type                                                           | Description                            |
| --------- | -------------------------------------------------------------- | -------------------------------------- |
| `req`     | [`DepositRequest`](/reference/wavelength-core/#DepositRequest) | Optional. Defaults to {} when omitted. |

Returns`Promise<DepositResult>`

The boarding address and its initial [`Entry`](#Entry) in the activity feed.

**`DepositRequest`**

```ts
type DepositRequest = {
  amountSatHint?: number;
};
```

| Parameter       | Type     | Description                                                              |
| --------------- | -------- | ------------------------------------------------------------------------ |
| `amountSatHint` | `number` | Optional. A hint for the amount (in sats) the caller intends to deposit. |

**`DepositResult`**

```ts
type DepositResult = {
  address: string;
  entry: Entry;
};
```

| Parameter | Type                                         | Description                                          |
| --------- | -------------------------------------------- | ---------------------------------------------------- |
| `address` | `string`                                     | The boarding (on-chain) address to deposit to.       |
| `entry`   | [`Entry`](/reference/wavelength-core/#Entry) | The activity entry tracking this deposit; see Entry. |

## receive

function

Generates a receive invoice for the requested amount.

```ts
receive(req: ReceiveRequest): Promise<ReceiveResult>
```

| Parameter | Type                                                           | Description                                |
| --------- | -------------------------------------------------------------- | ------------------------------------------ |
| `req`     | [`ReceiveRequest`](/reference/wavelength-core/#ReceiveRequest) | The amount (and optional memo) to request. |

Returns`Promise<ReceiveResult>`

The invoice and its initial [`Entry`](#Entry) in the activity feed.

**`ReceiveRequest`**

```ts
type ReceiveRequest = {
  amountSat: number;
  memo?: string;
};
```

| Parameter   | Type     | Description                               |
| ----------- | -------- | ----------------------------------------- |
| `amountSat` | `number` | The amount to request, in sats.           |
| `memo`      | `string` | Optional. A memo attached to the invoice. |

**`ReceiveResult`**

```ts
type ReceiveResult = {
  invoice: string;
  entry: Entry;
};
```

| Parameter | Type                                         | Description                                          |
| --------- | -------------------------------------------- | ---------------------------------------------------- |
| `invoice` | `string`                                     | The BOLT-11 Lightning invoice to be paid.            |
| `entry`   | [`Entry`](/reference/wavelength-core/#Entry) | The activity entry tracking this receive; see Entry. |

## Sending payments

Sending a payment follows a quote → confirm → pay flow. [`prepareSend()`](#prepareSend) validates the request and returns a quote (the expected fee, rail, and a single-use `sendIntentId`) without moving funds; [`sendPrepared()`](#sendPrepared) then dispatches that exact quote. [`send()`](#send) folds both steps into one call for the common case where you do not need to show the user a confirmation screen between quoting and paying.

## prepareSend

function

Quotes a payment without dispatching it: validates the request and returns the expected fee, settlement rail, and a single-use `sendIntentId`. Pair it with [`sendPrepared()`](#sendPrepared) for a quote → confirm → pay flow.

```ts
prepareSend(req: SendRequest): Promise<PrepareSendResult>
```

| Parameter | Type                                                     | Description                                                    |
| --------- | -------------------------------------------------------- | -------------------------------------------------------------- |
| `req`     | [`SendRequest`](/reference/wavelength-core/#SendRequest) | The Lightning invoice or on-chain address to quote a send for. |

Returns`Promise<PrepareSendResult>`

The quote: fee, rail, and the `sendIntentId` to pass to `sendPrepared()`.

## sendPrepared

function

Dispatches a payment previously quoted by [`prepareSend()`](#prepareSend).

```ts
sendPrepared(prepared: PrepareSendResult): Promise<SendResult>
```

| Parameter  | Type                                                                 | Description                                                                                                                             |
| ---------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `prepared` | [`PrepareSendResult`](/reference/wavelength-core/#PrepareSendResult) | The quote returned by prepareSend(). Its sendIntentId is consumed on dispatch; if dispatch fails, prepare a fresh send before retrying. |

Returns`Promise<SendResult>`

The dispatched send’s activity entry and actual amounts.

## send

function

Quotes and dispatches a payment in a single call, folding [`prepareSend()`](#prepareSend) and [`sendPrepared()`](#sendPrepared) together.

```ts
send(req: SendRequest): Promise<SendResult>
```

| Parameter | Type                                                     | Description                                       |
| --------- | -------------------------------------------------------- | ------------------------------------------------- |
| `req`     | [`SendRequest`](/reference/wavelength-core/#SendRequest) | The Lightning invoice or on-chain address to pay. |

Returns`Promise<SendResult>`

The dispatched send’s activity entry and actual amounts.

## SendRequest

type

Parameters accepted by [`prepareSend()`](#prepareSend) and [`send()`](#send), as a discriminated union: supply `invoice` for a Lightning send or `onchainAddress` for an on-chain send. The two arms are mutually exclusive, and `sweepAll` applies only to the on-chain arm.

```ts
type SendRequest =
  | {
      invoice: string;
      amountSat?: number;
      note?: string;
      maxFeeSat?: number;
    }
  | {
      onchainAddress: string;
      amountSat?: number;
      sweepAll?: boolean;
      note?: string;
      maxFeeSat?: number;
    };
```

**Lightning arm**

| Parameter   | Type     | Description                                                                                                        |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| `invoice`   | `string` | A Lightning invoice to pay.                                                                                        |
| `amountSat` | `number` | Optional. The amount to send, in sats. Ignored on the invoice path: v1 requires an amount-bearing BOLT-11 invoice. |
| `note`      | `string` | Optional. A note recorded with the activity.                                                                       |
| `maxFeeSat` | `number` | Optional. A cap on the fee, in sats.                                                                               |

**On-chain arm**

| Parameter        | Type      | Description                                                                  |
| ---------------- | --------- | ---------------------------------------------------------------------------- |
| `onchainAddress` | `string`  | An on-chain address to pay.                                                  |
| `amountSat`      | `number`  | Optional. The amount to send, in sats. Provide this or set sweepAll.         |
| `sweepAll`       | `boolean` | Optional. When true, sweeps the entire spendable balance to the destination. |
| `note`           | `string`  | Optional. A note recorded with the activity.                                 |
| `maxFeeSat`      | `number`  | Optional. A cap on the fee, in sats.                                         |

## PrepareSendResult

type

The quote and intent id returned by [`prepareSend()`](#prepareSend).

```ts
type PrepareSendResult = {
  sendIntentId: string;
  amountSat: number;
  expectedFeeSat: number;
  feeKnown: boolean;
  expectedTotalOutflowSat: number;
  totalOutflowKnown: boolean;
  rail: SendRail;
  quoteStatus: 'unspecified' | 'complete' | 'local_only';
  destinationSummary: string;
  invoiceDescription: string;
  paymentHash: string;
  expiresAtUnix: number;
  selectedOutpoints: string[];
  warning: string;
};
```

| Parameter                 | Type                                               | Description                                                                                                                          |
| ------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `sendIntentId`            | `string`                                           | Single-use id identifying this quote; pass the whole result object to sendPrepared() to dispatch it.                                 |
| `amountSat`               | `number`                                           | The amount that will be sent, in sats.                                                                                               |
| `expectedFeeSat`          | `number`                                           | The expected fee, in sats.                                                                                                           |
| `feeKnown`                | `boolean`                                          | Whether expectedFeeSat is a firm quote rather than an estimate.                                                                      |
| `expectedTotalOutflowSat` | `number`                                           | The expected total amount leaving the wallet (amount plus fee), in sats.                                                             |
| `totalOutflowKnown`       | `boolean`                                          | Whether expectedTotalOutflowSat is firm rather than an estimate.                                                                     |
| `rail`                    | [`SendRail`](/reference/wavelength-core/#SendRail) | The settlement rail this send is expected to use.                                                                                    |
| `quoteStatus`             | `'unspecified' \| 'complete' \| 'local_only'`      | How complete the prepare-time quote is: complete means the fee is fully known; local\_only means only a local estimate was possible. |
| `destinationSummary`      | `string`                                           | A human-readable summary of the destination.                                                                                         |
| `invoiceDescription`      | `string`                                           | The invoice's embedded description, for Lightning sends.                                                                             |
| `paymentHash`             | `string`                                           | The Lightning payment hash, when applicable.                                                                                         |
| `expiresAtUnix`           | `number`                                           | Unix timestamp after which this quote (and its sendIntentId) is no longer valid.                                                     |
| `selectedOutpoints`       | `string[]`                                         | The VTXO outpoints selected to fund this send; sendPrepared() spends exactly this set.                                               |
| `warning`                 | `string`                                           | An optional human-readable warning about this quote (e.g. a high fee).                                                               |

## SendResult

type

The result of a dispatched send, returned by [`sendPrepared()`](#sendPrepared) and [`send()`](#send).

```ts
type SendResult = {
  entry: Entry;
  actualAmountSat: number;
  paymentHash?: string;
};
```

| Parameter         | Type                                         | Description                                                                                                                                                                                                                                                                                                         |
| ----------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `entry`           | [`Entry`](/reference/wavelength-core/#Entry) | The activity entry tracking this send; see Entry.                                                                                                                                                                                                                                                                   |
| `actualAmountSat` | `number`                                     | The real amount that left the wallet. For invoice sends this matches the invoice principal; for a bounded on-chain send it matches the requested amount; for a sweep-all send it reflects the swept VTXO total, so echo it back to the user before treating the send as confirmed.                                  |
| `paymentHash`     | `string`                                     | Optional. The Lightning payment hash, when the send produced one. The daemon returns this from prepareSend (not sendPrepared), so the client folds it into send()'s result here; prefer this field over digging into entry.progress or entry.request, and note that entry.id is an activity id, not a payment hash. |

## SendRail

type

Identifies the expected settlement rail for a prepared send.

```ts
type SendRail =
  | 'unspecified'
  | 'offchain_unknown'
  | 'in_ark'
  | 'lightning'
  | 'onchain'
  | 'credit'
  | 'mixed';
```

| Value              | Meaning                                                       |
| ------------------ | ------------------------------------------------------------- |
| `unspecified`      | No rail could be determined.                                  |
| `offchain_unknown` | An off-chain rail was used but the specific one is not known. |
| `in_ark`           | Settled directly within Ark, without leaving the protocol.    |
| `lightning`        | Settled over Lightning (via a swap).                          |
| `onchain`          | Settled with an on-chain transaction.                         |
| `credit`           | Settled from the wallet’s server-side credit balance.         |
| `mixed`            | Settled by combining credit with the normal vHTLC path.       |

## classifyDestination

function

Classifies a pasted destination string so a send UI can render only the fields that apply to it. Pure, synchronous, and offline: it reads a BOLT-11 amount from the invoice’s human-readable part without decoding the bech32 payload, so an amountless invoice is detected before any network call.

```ts
function classifyDestination(raw: string): Destination
```

> **Note**
>
> `classifyDestination` deliberately does **not** name a settlement rail. A string it reports as `invoice` may still quote as `in_ark`, `credit`, or `mixed` (an address always settles `onchain`). Read [`rail`](#SendRail) from the [`PrepareSendResult`](#PrepareSendResult) for the authoritative answer, and treat any rail shown before that as provisional.

## Destination

type

The result of [`classifyDestination()`](#classifyDestination).

```ts
type Destination =
  | { kind: 'empty' }
  | { kind: 'invoice'; amount: InvoiceAmount }
  | { kind: 'address' };
```

| Parameter                     | Type      | Description                                                                                                                                                                                                                                                                            |
| ----------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ kind: 'empty' }`           | `variant` | The input is blank. Render no conditional fields.                                                                                                                                                                                                                                      |
| `{ kind: 'invoice', amount }` | `variant` | A BOLT-11 invoice. amount is the InvoiceAmount read from the human-readable part; see below. The daemon ignores a caller-supplied amountSat on the invoice path, and the current daemon rejects an amountless invoice outright, so a UI should never collect an amount for an invoice. |
| `{ kind: 'address' }`         | `variant` | Anything that is not a BOLT-11 invoice. Treat it as a payable address; the rail is still unknown.                                                                                                                                                                                      |

## InvoiceAmount

type

The amount an invoice carries, when it can be read from the human-readable part. A discriminated union keyed on `status`.

```ts
type InvoiceAmount =
  | { status: 'known'; sat: number }
  | { status: 'amountless' }
  | { status: 'unrepresentable' };
```

| Parameter                       | Type      | Description                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ status: 'known', sat }`      | `variant` | A whole number of satoshis, read directly from the invoice.                                                                                                                                                                                                                                                                                     |
| `{ status: 'amountless' }`      | `variant` | The invoice carries no amount at all. The payer must supply one; the current daemon rejects such an invoice outright.                                                                                                                                                                                                                           |
| `{ status: 'unrepresentable' }` | `variant` | The invoice carries an amount that cannot be shown as a whole number of satoshis: a sub-satoshi figure, or one too large to represent exactly. The invoice is still amount-bearing and the daemon pays it (a sub-satoshi amount is rounded up to the next satoshi), so a UI must not ask the payer for an amount. It simply cannot display one. |

## Activity and history

## list

function

Lists wallet activity or UTXOs per the request.

```ts
list(req?: ListRequest): Promise<ListResult>
```

| Parameter | Type                                                     | Description                                                |
| --------- | -------------------------------------------------------- | ---------------------------------------------------------- |
| `req`     | [`ListRequest`](/reference/wavelength-core/#ListRequest) | Optional. Defaults to {} (the activity view) when omitted. |

Returns`Promise<ListResult>`

A tagged union with only the field matching the requested view populated.

Filter the activity view by one or more entry kinds:

```ts
await client.list({
  view: 'activity',
  kinds: ['receive', 'deposit'],
});
```

**`ListRequest`**

```ts
type ListRequest = {
  view?: ListView;
  pendingOnly?: boolean;
  kinds?: EntryKind[];
  limit?: number;
  offset?: number;
  cursor?: string;
};
```

| Parameter     | Type                                               | Description                                                                                                                                                                                                 |
| ------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `view`        | [`ListView`](/reference/wavelength-core/#ListView) | Optional. Which view to list: activity entries, VTXOs, or on-chain outputs. Default: 'activity'.                                                                                                            |
| `pendingOnly` | `boolean`                                          | Optional. When true, returns only pending items. Applies to the activity view only.                                                                                                                         |
| `kinds`       | `EntryKind[]`                                      | Optional. Returns only the selected entry kinds. Applies to the activity view only.                                                                                                                         |
| `limit`       | `number`                                           | Optional. The maximum number of items to return; zero uses the daemon default.                                                                                                                              |
| `offset`      | `number`                                           | Optional. The number of items to skip for pagination. Applies to the vtxos and onchain views only; the activity view paginates by cursor and ignores offset.                                                |
| `cursor`      | `string`                                           | Optional. The opaque pagination token for the activity view. Empty starts from the newest entry; otherwise pass the nextCursor from the previous ActivityList page. Ignored by the vtxos and onchain views. |

**`ListResult`**

A tagged union on `view`: exactly one of `activity`, `vtxos`, or `onchain` is populated, matching the requested (or default) view. Switch on `view` to read the right field.

```ts
type ListResult = {
  view: ListView;
  activity?: ActivityList;
  vtxos?: VTXOInventory;
  onchain?: OnchainHistory;
};
```

| Parameter  | Type                                                           | Description                                                                                         |
| ---------- | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `view`     | [`ListView`](/reference/wavelength-core/#ListView)             | The populated variant. Mirrors the request’s view; an empty request view is reported as 'activity'. |
| `activity` | [`ActivityList`](/reference/wavelength-core/#ActivityList)     | Populated when view === 'activity'.                                                                 |
| `vtxos`    | [`VTXOInventory`](/reference/wavelength-core/#VTXOInventory)   | Populated when view === 'vtxos'. See the balances-and-vtxos guide for the VTXO shape.               |
| `onchain`  | [`OnchainHistory`](/reference/wavelength-core/#OnchainHistory) | Populated when view === 'onchain'.                                                                  |

**`ListView`**

```ts
type ListView = 'activity' | 'vtxos' | 'onchain';
```

| Value      | Meaning                                                             |
| ---------- | ------------------------------------------------------------------- |
| `activity` | The merged send/receive/deposit/exit activity feed. Default.        |
| `vtxos`    | The live VTXO inventory.                                            |
| `onchain`  | The on-chain transaction history (boarding, sweeps, leave outputs). |

**`ActivityList`**

```ts
type ActivityList = {
  entries: Entry[];
  total: number;
  hasMore: boolean;
  nextCursor: string;
};
```

| Parameter    | Type      | Description                                                                                                                           |
| ------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `entries`    | `Entry[]` | The matching activity entries; see Entry.                                                                                             |
| `total`      | `number`  | The number of entries on this page, not a full-feed count. The feed is cursor-paged, so use hasMore to decide whether to fetch again. |
| `hasMore`    | `boolean` | Whether more entries exist after this page.                                                                                           |
| `nextCursor` | `string`  | The token to pass as ListRequest.cursor to fetch the next page. Empty when hasMore is false.                                          |

## VTXOInventory

type

The paginated inventory returned for the `vtxos` list view.

```ts
type VTXOInventory = {
  vtxos: WalletVTXO[];
  total: number;
};
```

| Parameter | Type           | Description                         |
| --------- | -------------- | ----------------------------------- |
| `vtxos`   | `WalletVTXO[]` | The VTXOs on the current page.      |
| `total`   | `number`       | The total number of matching VTXOs. |

## WalletVTXO

type

One spendable or spent VTXO in a wallet inventory.

```ts
type WalletVTXO = {
  outpoint: string;
  amountSat: number;
  status: string;
  batchExpiry: number;
  relativeExpiry: number;
  commitmentTxid: string;
};
```

## OnchainHistory

type

The paginated history returned for the `onchain` list view.

```ts
type OnchainHistory = {
  txs: OnchainTx[];
  total: number;
  hasMore: boolean;
};
```

| Parameter | Type          | Description                                    |
| --------- | ------------- | ---------------------------------------------- |
| `txs`     | `OnchainTx[]` | The on-chain transactions on the current page. |
| `total`   | `number`      | The total number of matching transactions.     |
| `hasMore` | `boolean`     | Whether another page is available.             |

## OnchainTx

type

One transaction in the on-chain history returned by the daemon.

```ts
type OnchainTx = {
  txid: string;
  kind: string;
  amountSat: number;
  feeSat: number;
  status: string;
  confirmationHeight: number;
  createdAt: string;
  description: string;
};
```

## subscribe

function

Subscribes a listener to runtime events.

```ts
subscribe(listener: WavelengthListener): () => void
```

| Parameter  | Type                                                                   | Description                                 |
| ---------- | ---------------------------------------------------------------------- | ------------------------------------------- |
| `listener` | [`WavelengthListener`](/reference/wavelength-core/#WavelengthListener) | Callback invoked with each WavelengthEvent. |

Returns`() => void`

An unsubscribe function; call it to stop receiving events on this listener.

**`WavelengthListener`**

```ts
type WavelengthListener = (event: WavelengthEvent) => void;
```

See [`WavelengthEvent`](#WavelengthEvent) in the events section below for the event shapes delivered to a listener.

## startActivity

function

Opens the wallet activity stream and forwards each entry to subscribers as an `'activity'` event until [`stopActivity()`](#stopActivity) is called.

```ts
startActivity(opts?: ActivityStreamOptions): Promise<void>
```

```ts
// Replay entries that already exist, then continue with new activity.
await client.startActivity({
  includeExisting: true,
  kinds: ['send', 'receive'],
});

// Resume after the last entry this consumer processed.
await client.startActivity({
  kinds: ['send', 'receive'],
  cursor: lastCursor,
});
```

| Parameter              | Type          | Description                                                                                                                  |
| ---------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `opts.includeExisting` | `boolean`     | Optional. When true, immediately emits an activity event for every entry that already exists, in addition to future changes. |
| `opts.kinds`           | `EntryKind[]` | Optional. Streams only the selected activity kinds.                                                                          |
| `opts.cursor`          | `number`      | Optional. Resumes after the last monotonic Entry.cursor the consumer processed. Must be a nonnegative safe integer.          |

**`ActivityStreamOptions`**

```ts
type ActivityStreamOptions = {
  includeExisting?: boolean;
  kinds?: EntryKind[];
  cursor?: number;
};
```

Returns`Promise<void>`

Resolves once the activity stream is open.

A direct `WavelengthClient` receives an `activityStream` event when the stream ends or fails and chooses its own retry policy. [`WalletEngine`](#WalletEngine) adds reconciliation and bounded cursor-based recovery for apps that want that managed behavior.

## stopActivity

function

Closes the activity stream opened by [`startActivity()`](#startActivity).

```ts
stopActivity(): void
```

Returns`void`

Nothing; stops emitting `'activity'` events synchronously.

## Entry

type

A single row in the wallet activity feed, returned by [`list()`](#list) and streamed via [`startActivity()`](#startActivity) as `activity` events.

```ts
type Entry = {
  id: string;
  kind: EntryKind;
  status: EntryStatus;
  amountSat: number;
  feeSat: number;
  counterparty: string;
  createdAt: string;
  updatedAt: string;
  note: string;
  failureReason: string;
  failureCode: EntryFailureCode;
  cursor: number;
  progress?: EntryProgress;
  request?: EntryRequest;
};
```

| Parameter       | Type                                                               | Description                                                                                                                                                              |
| --------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`            | `string`                                                           | The activity id. Not a payment hash; see SendResult.paymentHash for that.                                                                                                |
| `kind`          | [`EntryKind`](/reference/wavelength-core/#EntryKind)               | The user-visible activity category.                                                                                                                                      |
| `status`        | [`EntryStatus`](/reference/wavelength-core/#EntryStatus)           | The collapsed pending/complete/failed state. See the Phase vs Status note below.                                                                                         |
| `amountSat`     | `number`                                                           | The activity amount, in sats.                                                                                                                                            |
| `feeSat`        | `number`                                                           | The fee associated with this activity, in sats.                                                                                                                          |
| `counterparty`  | `string`                                                           | A human-readable counterparty label, when known.                                                                                                                         |
| `createdAt`     | `string`                                                           | When the entry was created.                                                                                                                                              |
| `updatedAt`     | `string`                                                           | When the entry was last updated.                                                                                                                                         |
| `note`          | `string`                                                           | An optional note recorded with the activity.                                                                                                                             |
| `failureReason` | `string`                                                           | Human-readable supplement to failureCode; populated only when status is 'failed'.                                                                                        |
| `failureCode`   | [`EntryFailureCode`](/reference/wavelength-core/#EntryFailureCode) | Stable, machine-readable classification of why the entry failed. Empty unless status is 'failed'.                                                                        |
| `cursor`        | `number`                                                           | The monotonic position of this update on the activity stream. Persist it to resume with ActivityStreamOptions.cursor. It is zero on entries returned outside the stream. |
| `progress`      | [`EntryProgress`](/reference/wavelength-core/#EntryProgress)       | Optional. Lifecycle metadata the daemon normalized for this entry. Absent when the backing subsystem supplied no progress hint.                                          |
| `request`       | [`EntryRequest`](/reference/wavelength-core/#EntryRequest)         | Optional. The user-recognizable request that created the entry (an invoice, address, or Ark address). Absent when the backing subsystem did not persist one.             |

## EntryProgress

type

The wrapper-owned view of the lifecycle metadata the daemon computes for an [`Entry`](#Entry). Fields are populated on a best-effort basis by the backing subsystem; an empty field means not applicable or not yet known.

```ts
type EntryProgress = {
  phase: EntryPhase;
  phaseLabel: string;
  paymentHash: string;
  txid: string;
  confirmationHeight: number;
  vTXOOutpoint: string;
  preimage: string;
};
```

| Parameter            | Type                                                   | Description                                                                                                                           |
| -------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| `phase`              | [`EntryPhase`](/reference/wavelength-core/#EntryPhase) | The coarse lifecycle phase for the entry.                                                                                             |
| `phaseLabel`         | `string`                                               | The short lowercase label the daemon emitted; render this directly instead of switching on phase if you prefer.                       |
| `paymentHash`        | `string`                                               | Populated for Lightning-backed send/receive entries.                                                                                  |
| `txid`               | `string`                                               | Populated when the backing ledger row has an on-chain txid.                                                                           |
| `confirmationHeight` | `number`                                               | Populated once the source records it.                                                                                                 |
| `vTXOOutpoint`       | `string`                                               | Populated when a swap observes the Ark vHTLC output.                                                                                  |
| `preimage`           | `string`                                               | The hex-encoded Lightning payment preimage when known. For a completed Lightning-backed send, it is proof of payment for the invoice. |

## EntryRequest

type

The wrapper-owned, flattened view of the request that created an [`Entry`](#Entry). Exactly one variant’s fields are populated, named by `type`; read `type` first and treat the other fields as zero.

```ts
type EntryRequest = {
  type: EntryRequestType;
  lightningInvoice: string;
  paymentHash: string;
  onchainAddress: string;
  arkAddress: string;
};
```

| Parameter          | Type                                                               | Description                                                                                                                                 |
| ------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`             | [`EntryRequestType`](/reference/wavelength-core/#EntryRequestType) | Names the populated variant.                                                                                                                |
| `lightningInvoice` | `string`                                                           | The BOLT-11 payment request. Populated when type is 'lightning'.                                                                            |
| `paymentHash`      | `string`                                                           | Identifies the Lightning invoice and stays stable after the invoice is no longer convenient to display. Populated when type is 'lightning'. |
| `onchainAddress`   | `string`                                                           | The bech32 on-chain address originally issued or targeted. Populated when type is 'onchain'.                                                |
| `arkAddress`       | `string`                                                           | The Ark address originally issued or targeted. Populated when type is 'ark'.                                                                |

## EntryKind

type

The user-visible wallet activity category.

```ts
type EntryKind = 'send' | 'receive' | 'deposit' | 'exit';
```

| Value     | Meaning                                 |
| --------- | --------------------------------------- |
| `send`    | An outbound wallet payment.             |
| `receive` | An inbound Lightning-to-wallet receive. |
| `deposit` | A boarding on-chain deposit.            |
| `exit`    | A cooperative wallet-to-on-chain exit.  |

## EntryStatus

type

The collapsed wallet activity state.

```ts
type EntryStatus = 'pending' | 'complete' | 'failed';
```

| Value      | Meaning                                  |
| ---------- | ---------------------------------------- |
| `pending`  | The activity is still in flight.         |
| `complete` | The activity finished successfully.      |
| `failed`   | The activity reached a terminal failure. |

## EntryPhase

type

A coarse, wrapper-owned lifecycle phase for an [`Entry`](#Entry).

```ts
type EntryPhase =
  | 'unspecified'
  | 'request_created'
  | 'waiting_for_payment'
  | 'payment_detected'
  | 'settling'
  | 'confirmed'
  | 'refunding'
  | 'refunded'
  | 'failed'
  | 'waiting_for_confirmation';
```

| Value                      | Meaning                                                                  |
| -------------------------- | ------------------------------------------------------------------------ |
| `unspecified`              | The backing subsystem provided no lifecycle hint.                        |
| `request_created`          | The request was created but no payment has been observed yet.            |
| `waiting_for_payment`      | The wallet is waiting for an inbound payment or swap funding.            |
| `payment_detected`         | A payment was detected but is not yet settled.                           |
| `settling`                 | The operation is settling through Ark, Lightning, or on-chain machinery. |
| `confirmed`                | The backing operation is confirmed or otherwise durably complete.        |
| `refunding`                | The operation is currently refunding.                                    |
| `refunded`                 | The refund path completed.                                               |
| `failed`                   | The backing operation reached a terminal failed state.                   |
| `waiting_for_confirmation` | An on-chain payment was detected and is waiting for block confirmation.  |

> **Phase vs. Status**
>
> `EntryStatus` answers only pending/complete/failed; `EntryPhase` explains the current backing-system step within that status (for example, a `pending` entry might be `waiting_for_payment` or `settling`). Use `status` for coarse UI state and `progress.phase` when you want to show the reader more detail about what is currently happening.

## EntryFailureCode

type

A wrapper-owned, stable classification of why a failed [`Entry`](#Entry) failed.

```ts
type EntryFailureCode =
  | 'timed_out'
  | 'expired'
  | 'refunded'
  | 'needs_intervention'
  | 'failed';
```

| Value                | Meaning                                                                      |
| -------------------- | ---------------------------------------------------------------------------- |
| `timed_out`          | The operation exceeded the wallet deadline before reaching a terminal state. |
| `expired`            | The swap expired before it was funded.                                       |
| `refunded`           | An outbound payment was refunded back to the wallet.                         |
| `needs_intervention` | The swap reached an anomalous state requiring manual recovery.               |
| `failed`             | A generic terminal failure with no more specific classification.             |

## EntryRequestType

type

Discriminates which request shape an [`EntryRequest`](#EntryRequest) carries.

```ts
type EntryRequestType = 'lightning' | 'onchain' | 'ark';
```

| Value       | Meaning                                                                               |
| ----------- | ------------------------------------------------------------------------------------- |
| `lightning` | A Lightning send/receive request; `lightningInvoice` and `paymentHash` are populated. |
| `onchain`   | A deposit/exit request; `onchainAddress` is populated.                                |
| `ark`       | A direct Ark send/receive request; `arkAddress` is populated.                         |

## Exiting Ark

> **Preview before you broadcast**
>
> `getExitPlan()` and `sweepWallet({ broadcast: false })` (the default) let you preview an exit or sweep, including required funding and fees, without moving any funds. Always show the preview to the user and get explicit confirmation before calling `sweepWallet({ broadcast: true })`, since that call moves funds and cannot be undone.

## exit

function

Exits a single outpoint through one explicit branch: a cooperative leave, optionally to `destination`, or an acknowledged unilateral unroll. When `destination` is omitted, the daemon generates a fresh backing-wallet address.

```ts
exit(req: ExitRequest): Promise<ExitResult>
```

| Parameter | Type                                                     | Description                                                                                          |
| --------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `req`     | [`ExitRequest`](/reference/wavelength-core/#ExitRequest) | The outpoint and either an optional cooperative destination or the exact unilateral acknowledgement. |

Returns`Promise<ExitResult>`

The outcome, discriminated by `path`.

**`ExitRequest`**

`destination` and `forceUnrollAck` are mutually exclusive. Omit both to make a cooperative exit to a fresh backing-wallet address:

```ts
await client.exit({ outpoint });
```

A cooperative error rejects the call and never falls back to unilateral unroll. Starting unilateral unroll requires the exported `FORCE_UNROLL_ACK` constant:

```ts
await client.exit({
  outpoint,
  forceUnrollAck: FORCE_UNROLL_ACK,
});
```

```ts
type ExitRequest =
  | {
      outpoint: string;
      destination?: string;
      forceUnrollAck?: never;
    }
  | {
      outpoint: string;
      destination?: never;
      forceUnrollAck: typeof FORCE_UNROLL_ACK;
    };

const FORCE_UNROLL_ACK = 'I_KNOW_WHAT_I_AM_DOING' as const;
```

| Parameter        | Type                      | Description                                                                                                                                                                                        |
| ---------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `outpoint`       | `string`                  | The VTXO outpoint to exit, in "txid:index" format.                                                                                                                                                 |
| `destination`    | `string`                  | Optional. Cooperative branch only. The on-chain address that receives the leave output. When omitted, the daemon generates a fresh backing-wallet address. Mutually exclusive with forceUnrollAck. |
| `forceUnrollAck` | `typeof FORCE_UNROLL_ACK` | Unilateral branch only. Must be the exact exported acknowledgement constant and cannot be combined with destination.                                                                               |

**`ExitResult`**

A tagged union over the three exit paths. Read `path` first and only inspect the variant fields associated with that path; the remaining fields are zero-valued.

```ts
type ExitResult = {
  path: ExitPath;
  cooperative: boolean;
  queuedOutpoints: string[];
  created: boolean;
  actorID: string;
  cooperativeError: string;
};
```

| Parameter          | Type                                               | Description                                                                                                                                                   |
| ------------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `path`             | [`ExitPath`](/reference/wavelength-core/#ExitPath) | Discriminates between the three legal outcomes; switch on this before reading the variant fields below.                                                       |
| `cooperative`      | `boolean`                                          | true iff path === 'cooperative'. Retained for backwards compatibility; prefer path.                                                                           |
| `queuedOutpoints`  | `string[]`                                         | The outpoints the cooperative leave admitted into a round. Populated only when path === 'cooperative'.                                                        |
| `created`          | `boolean`                                          | Whether the unilateral-unroll path spawned a fresh job. Populated when path is 'unilateral' or 'unilateral\_fallback'.                                        |
| `actorID`          | `string`                                           | Identifies the durable unroll job that owns the unilateral path. Populated when path is 'unilateral' or 'unilateral\_fallback'.                               |
| `cooperativeError` | `string`                                           | Retained for source compatibility with a prior SDK fallback shape; current daemon behavior returns cooperative failures directly rather than populating this. |

**`ExitPath`**

```ts
type ExitPath = 'cooperative' | 'unilateral' | 'unilateral_fallback';
```

| Value                 | Meaning                                                                                                                                                                          |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cooperative`         | The cooperative leave was admitted by the operator; `queuedOutpoints` carries the round’s selection echo. Round completion is asynchronous; subscribe to confirm terminal state. |
| `unilateral`          | The caller supplied the exact force acknowledgement and the daemon started unilateral unroll; `created` and `actorID` describe the job.                                          |
| `unilateral_fallback` | Retained for source compatibility with a prior SDK result shape. Current wallet RPC behavior never returns this path, since cooperative failures are surfaced directly.          |

## exitStatus

function

Queries the status of an exit.

```ts
exitStatus(req: ExitStatusRequest): Promise<ExitStatusResult>
```

| Parameter | Type                                                                 | Description                                |
| --------- | -------------------------------------------------------------------- | ------------------------------------------ |
| `req`     | [`ExitStatusRequest`](/reference/wavelength-core/#ExitStatusRequest) | The outpoint whose exit status is queried. |

Returns`Promise<ExitStatusResult>`

Whether a job exists for the outpoint, and its current status.

**`ExitStatusRequest`**

```ts
type ExitStatusRequest = {
  outpoint: string;
  detailed?: boolean;
};
```

| Parameter  | Type      | Description                                                                                                                                                                                                                              |
| ---------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `outpoint` | `string`  | The VTXO outpoint whose exit status is queried.                                                                                                                                                                                          |
| `detailed` | `boolean` | Optional. Request recovery-tree progress, a CSV maturity countdown, a fee breakdown, and a best-case block countdown. It costs one live actor round-trip plus a fee estimate, so leave it false for a coarse, cheaper phase-only status. |

**`ExitStatusResult`**

`found` is false when no job exists for the requested outpoint; that is not an error condition. The detailed fields (`phaseDetail`, `progress`, `cSV`, `fees`, `bestCaseBlocksRemaining`, `currentHeight`) are populated only when the request set `detailed`; otherwise they are empty, nil, or zero.

```ts
type ExitStatusResult = {
  found: boolean;
  status: ExitJobStatus;
  sweepTxid: string;
  lastError: string;
  phaseDetail: string;
  progress?: ExitProgress;
  cSV?: ExitCSV;
  fees?: ExitFees;
  bestCaseBlocksRemaining: number;
  currentHeight: number;
};
```

| Parameter                 | Type                                                         | Description                                                                                                   |
| ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `found`                   | `boolean`                                                    | Whether an exit job exists for the requested outpoint.                                                        |
| `status`                  | [`ExitJobStatus`](/reference/wavelength-core/#ExitJobStatus) | The job’s current status. Meaningful only when found is true.                                                 |
| `sweepTxid`               | `string`                                                     | The sweep transaction id, once known.                                                                         |
| `lastError`               | `string`                                                     | The last error the job recorded, if any.                                                                      |
| `phaseDetail`             | `string`                                                     | A one-line human description of the current phase. Empty on a coarse (non-detailed) query.                    |
| `progress`                | [`ExitProgress`](/reference/wavelength-core/#ExitProgress)   | Recovery-tree materialization progress. Nil on a coarse query, or when no live actor backs the job.           |
| `cSV`                     | [`ExitCSV`](/reference/wavelength-core/#ExitCSV)             | The target’s CSV maturity countdown. Nil until the target confirms.                                           |
| `fees`                    | [`ExitFees`](/reference/wavelength-core/#ExitFees)           | The on-chain cost breakdown for the exit. Nil on a coarse query.                                              |
| `bestCaseBlocksRemaining` | `number`                                                     | The optimistic block count until a confirmed sweep. Zero on a coarse query.                                   |
| `currentHeight`           | `number`                                                     | The best block height the exit job has observed. Zero on a coarse query, or when no live actor backs the job. |

**`ExitProgress`**

Materialization progress through the recovery tree. Populated only for a detailed query against a live exit job.

```ts
type ExitProgress = {
  confirmedTxs: number;
  inFlightTxs: number;
  readyTxs: number;
  blockedTxs: number;
  totalTxs: number;
  currentLayer: number;
  totalLayers: number;
  targetConfirmed: boolean;
  allProofConfirmed: boolean;
};
```

| Parameter           | Type      | Description                                                                                                           |
| ------------------- | --------- | --------------------------------------------------------------------------------------------------------------------- |
| `confirmedTxs`      | `number`  | Proof transactions confirmed on-chain.                                                                                |
| `inFlightTxs`       | `number`  | Proof transactions broadcast but not yet observed confirmed.                                                          |
| `readyTxs`          | `number`  | Proof transactions ready to broadcast now.                                                                            |
| `blockedTxs`        | `number`  | Proof transactions still waiting on an unconfirmed in-proof parent.                                                   |
| `totalTxs`          | `number`  | Total transactions in the exit proof tree.                                                                            |
| `currentLayer`      | `number`  | The frontier layer index: the shallowest topological layer (roots first) that still holds an unconfirmed transaction. |
| `totalLayers`       | `number`  | The depth of the exit proof tree.                                                                                     |
| `targetConfirmed`   | `boolean` | True once the target VTXO transaction has confirmed.                                                                  |
| `allProofConfirmed` | `boolean` | True once every proof-tree transaction has confirmed, so only the CSV wait and final sweep remain.                    |

**`ExitCSV`**

The target’s CSV maturity countdown. Populated only once the target transaction has confirmed.

```ts
type ExitCSV = {
  targetConfirmHeight: number;
  maturityHeight: number;
  blocksRemaining: number;
  mature: boolean;
};
```

| Parameter             | Type      | Description                                           |
| --------------------- | --------- | ----------------------------------------------------- |
| `targetConfirmHeight` | `number`  | The height at which the target transaction confirmed. |
| `maturityHeight`      | `number`  | The height at which the CSV timelock matures.         |
| `blocksRemaining`     | `number`  | Blocks remaining until maturity.                      |
| `mature`              | `boolean` | Whether the CSV timelock has matured.                 |

**`ExitFees`**

The on-chain cost breakdown for the exit. The CPFP total is estimated; `sweepFeeActual` reports whether `sweepFeeSat` is the real built-sweep fee rather than an estimate.

```ts
type ExitFees = {
  cPFPFeeSat: number;
  sweepFeeSat: number;
  totalCostSat: number;
  spentSoFarSat: number;
  vTXOAmountSat: number;
  netRecoveredSat: number;
  feeRateSatVByte: number;
  sweepFeeActual: boolean;
};
```

| Parameter         | Type      | Description                                                                     |
| ----------------- | --------- | ------------------------------------------------------------------------------- |
| `cPFPFeeSat`      | `number`  | The estimated total CPFP fee, in sats.                                          |
| `sweepFeeSat`     | `number`  | The sweep fee, in sats. Real rather than estimated when sweepFeeActual is true. |
| `totalCostSat`    | `number`  | The projected on-chain cost of the whole exit, in sats.                         |
| `spentSoFarSat`   | `number`  | The estimated fee committed so far, in sats.                                    |
| `vTXOAmountSat`   | `number`  | The VTXO value being recovered, in sats.                                        |
| `netRecoveredSat` | `number`  | The estimated net recoverable after fees, in sats.                              |
| `feeRateSatVByte` | `number`  | The fee rate used, in sat/vByte.                                                |
| `sweepFeeActual`  | `boolean` | Whether sweepFeeSat is the real built-sweep fee rather than an estimate.        |

**`ExitJobStatus`**

Collapses the underlying unroll job phases to a short wallet-facing string set.

```ts
type ExitJobStatus =
  | 'unspecified'
  | 'pending'
  | 'materializing'
  | 'csv_pending'
  | 'sweeping'
  | 'completed'
  | 'failed';
```

| Value           | Meaning                                                     |
| --------------- | ----------------------------------------------------------- |
| `unspecified`   | No status hint available.                                   |
| `pending`       | The job has been created but has not started materializing. |
| `materializing` | The unilateral exit transaction is being built.             |
| `csv_pending`   | Waiting on the CSV timelock before the sweep can broadcast. |
| `sweeping`      | The sweep transaction has been broadcast.                   |
| `completed`     | The exit finished successfully.                             |
| `failed`        | The job reached a terminal failure.                         |

## exitSummary

function

Summarizes all in-progress exits: one entry per active exit plus wallet-wide totals for the amount being recovered, the estimated fees, and the estimated net recoverable. Completed and failed exits are omitted; they have no amount left to recover.

```ts
exitSummary(req?: ExitSummaryRequest): Promise<ExitSummaryResult>
```

| Parameter | Type                                                                   | Description                                                       |
| --------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `req`     | [`ExitSummaryRequest`](/reference/wavelength-core/#ExitSummaryRequest) | Takes no arguments; the daemon reports the wallet-wide portfolio. |

Returns`Promise<ExitSummaryResult>`

The in-progress exits plus aggregate totals.

**`ExitSummaryRequest`**

Takes no arguments.

```ts
type ExitSummaryRequest = Record<string, never>;
```

**`ExitSummaryResult`**

```ts
type ExitSummaryResult = {
  exits: ExitSummaryEntry[];
  totalExits: number;
  totalVTXOAmountSat: number;
  totalEstFeeSat: number;
  totalEstNetRecoveredSat: number;
};
```

| Parameter                 | Type                 | Description                                                 |
| ------------------------- | -------------------- | ----------------------------------------------------------- |
| `exits`                   | `ExitSummaryEntry[]` | One entry per in-progress exit.                             |
| `totalExits`              | `number`             | The number of in-progress exits.                            |
| `totalVTXOAmountSat`      | `number`             | The combined VTXO value being recovered, in sats.           |
| `totalEstFeeSat`          | `number`             | The combined estimated on-chain fees, in sats.              |
| `totalEstNetRecoveredSat` | `number`             | The combined estimated net recoverable after fees, in sats. |

**`ExitSummaryEntry`**

One in-progress exit’s coarse contribution to the portfolio.

```ts
type ExitSummaryEntry = {
  outpoint: string;
  status: ExitJobStatus;
  vTXOAmountSat: number;
  estTotalFeeSat: number;
  estNetRecoveredSat: number;
};
```

| Parameter            | Type                                                         | Description                                              |
| -------------------- | ------------------------------------------------------------ | -------------------------------------------------------- |
| `outpoint`           | `string`                                                     | The VTXO outpoint being exited.                          |
| `status`             | [`ExitJobStatus`](/reference/wavelength-core/#ExitJobStatus) | The exit job’s current status.                           |
| `vTXOAmountSat`      | `number`                                                     | The VTXO value being recovered, in sats.                 |
| `estTotalFeeSat`     | `number`                                                     | The estimated total on-chain fee for this exit, in sats. |
| `estNetRecoveredSat` | `number`                                                     | The estimated net recoverable after fees, in sats.       |

## getExitPlan

function

Previews unilateral-exit readiness (and the backing-wallet funding required) for a set of VTXO outpoints, without moving funds.

```ts
getExitPlan(req: GetExitPlanRequest): Promise<GetExitPlanResult>
```

| Parameter | Type                                                                   | Description                        |
| --------- | ---------------------------------------------------------------------- | ---------------------------------- |
| `req`     | [`GetExitPlanRequest`](/reference/wavelength-core/#GetExitPlanRequest) | The outpoints to plan an exit for. |

Returns`Promise<GetExitPlanResult>`

Per-outpoint funding plans plus aggregate totals.

**`GetExitPlanRequest`**

```ts
type GetExitPlanRequest = {
  outpoints: string[];
  confTarget?: number;
};
```

| Parameter    | Type       | Description                                                        |
| ------------ | ---------- | ------------------------------------------------------------------ |
| `outpoints`  | `string[]` | The VTXO outpoints to plan an exit for.                            |
| `confTarget` | `number`   | Optional. A confirmation target (in blocks) used to estimate fees. |

**`GetExitPlanResult`**

Describes the combined backing-wallet funding plan for every previewed outpoint plus aggregate totals.

```ts
type GetExitPlanResult = {
  plans: ExitPlanEntry[];
  feeRateSatPerVByte: number;
  canStart: boolean;
  totalFundingShortfallSat: number;
  totalRecommendedFundingSat: number;
};
```

| Parameter                    | Type              | Description                                                            |
| ---------------------------- | ----------------- | ---------------------------------------------------------------------- |
| `plans`                      | `ExitPlanEntry[]` | One entry per requested outpoint.                                      |
| `feeRateSatPerVByte`         | `number`          | The fee rate used to compute the plan.                                 |
| `canStart`                   | `boolean`         | Whether every outpoint in the plan is ready to exit right now.         |
| `totalFundingShortfallSat`   | `number`          | The combined backing-wallet funding still needed across all outpoints. |
| `totalRecommendedFundingSat` | `number`          | The combined recommended backing-wallet funding across all outpoints.  |

**`ExitPlanEntry`**

Describes how to fund the backing wallet before `exit()` for a single previewed VTXO outpoint.

```ts
type ExitPlanEntry = {
  outpoint: string;
  fundingAddress: string;
  requiredConfirmations: number;
  requiredFeeUTXOCount: number;
  usableFeeUTXOCount: number;
  recommendedUTXOAmountSat: number;
  recommendedTotalFundingSat: number;
  fundingShortfallSat: number;
  canStart: boolean;
  infeasibilityReason: ExitInfeasibilityReason;
  exitJobFound: boolean;
  exitStatus: ExitJobStatus;
  sweepTxid: string;
  lastError: string;
  err: string;
};
```

| Parameter                    | Type                                                                             | Description                                                                                                                                                       |
| ---------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `outpoint`                   | `string`                                                                         | The VTXO outpoint this entry describes.                                                                                                                           |
| `fundingAddress`             | `string`                                                                         | The backing-wallet address to fund for this exit.                                                                                                                 |
| `requiredConfirmations`      | `number`                                                                         | Confirmations the funding UTXO(s) need before the exit can start.                                                                                                 |
| `requiredFeeUTXOCount`       | `number`                                                                         | The number of fee UTXOs required.                                                                                                                                 |
| `usableFeeUTXOCount`         | `number`                                                                         | The number of fee UTXOs currently usable.                                                                                                                         |
| `recommendedUTXOAmountSat`   | `number`                                                                         | The recommended amount per funding UTXO, in sats.                                                                                                                 |
| `recommendedTotalFundingSat` | `number`                                                                         | The recommended total funding amount, in sats.                                                                                                                    |
| `fundingShortfallSat`        | `number`                                                                         | The funding still needed before this outpoint can exit, in sats.                                                                                                  |
| `canStart`                   | `boolean`                                                                        | Whether this outpoint is ready to exit right now.                                                                                                                 |
| `infeasibilityReason`        | [`ExitInfeasibilityReason`](/reference/wavelength-core/#ExitInfeasibilityReason) | Why canStart is false: a structural block (a dust or uneconomical VTXO) or a funding shortfall the wallet could cover. It is "unspecified" when canStart is true. |
| `exitJobFound`               | `boolean`                                                                        | Whether an exit job already exists for this outpoint.                                                                                                             |
| `exitStatus`                 | [`ExitJobStatus`](/reference/wavelength-core/#ExitJobStatus)                     | The existing job’s status, when exitJobFound is true.                                                                                                             |
| `sweepTxid`                  | `string`                                                                         | The sweep transaction id, once known.                                                                                                                             |
| `lastError`                  | `string`                                                                         | The last error the existing job recorded, if any.                                                                                                                 |
| `err`                        | `string`                                                                         | A per-outpoint failure encountered while building this plan entry (empty on success).                                                                             |

**`ExitInfeasibilityReason`**

Explains why a previewed exit cannot start. A structural block (dust or uneconomical) is one no amount of wallet funding fixes; the others are funding shortfalls the wallet could cover.

```ts
type ExitInfeasibilityReason =
  | 'unspecified'
  | 'sweep_below_dust'
  | 'uneconomical'
  | 'wallet_underfunded'
  | 'wallet_too_few_inputs';
```

| Value                   | Meaning                                                                                                                                         |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `unspecified`           | The exit is feasible, or the block is a plain funding shortfall reported via `fundingShortfallSat`.                                             |
| `sweep_below_dust`      | The swept output, after the sweep fee, would fall at or below the dust limit, so the sweep could never relay. Impossible regardless of funding. |
| `uneconomical`          | The total on-chain cost to recover the VTXO exceeds the configured fraction of its value.                                                       |
| `wallet_underfunded`    | The confirmed on-chain wallet balance is too small to cover the CPFP fees. Funding the wallet resolves it.                                      |
| `wallet_too_few_inputs` | The wallet has fewer usable confirmed UTXOs than the VTXO has independent ancestry paths, so it lacks distinct CPFP fee inputs.                 |

> **exitBatch starts exits and moves money**
>
> `exitBatch()` walks the given outpoints and calls [`exit()`](#exit) for each one in turn: it moves funds. It resolves once every exit has been **started**, not completed. A unilateral exit keeps running for hours or days after the promise settles; use [`exitStatus()`](#exitStatus) or [`exitSummary()`](#exitSummary) to follow it to completion. Funding is never reserved ahead of time, so on the unilateral path `exitBatch()` re-plans with [`getExitPlan()`](#getExitPlan) between starts: an earlier start can consume the fee inputs a later one needs, and re-planning is the only way to catch that before the later exit is attempted instead of after.

## exitBatch

function

Starts a batch of exits, one outpoint per [`exit()`](#exit) call, and reports which started, which were skipped, and which never started.

```ts
function exitBatch(
  opts: ExitBatchOptions & {
    client: WavelengthClient;
    signal?: AbortSignal;
    onEvent?: (event: ExitBatchEvent) => void;
  },
): Promise<ExitBatchResult>
```

On the unilateral path it previews funding with [`getExitPlan()`](#getExitPlan) before each start, skips outpoints that already have a running exit job, refuses to start anything if the wallet cannot fund the batch, and re-plans between starts, as the callout above explains. Because fee inputs are leased only at broadcast time, a mid-batch `exit()` rejection is treated as a clean stop rather than retried. On the cooperative path it queues each outpoint into the next round, one `exit()` call at a time, with no re-planning step.

| Parameter | Type                                                               | Description                                                                                                                                    |
| --------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `opts`    | [`ExitBatchOptions`](/reference/wavelength-core/#ExitBatchOptions) | The batch mode and outpoints, plus client (the WavelengthClient to drive), an optional AbortSignal, and an optional onEvent progress callback. |

Returns`Promise<ExitBatchResult>`

Which outpoints started, which were skipped because they already had a running exit, which never started, and why the batch stopped early, if it did.

**`ExitBatchOptions`**

A discriminated union on `mode`. A cooperative batch queues each outpoint into the next round to an optional on-chain `destination`; a unilateral batch forces each outpoint on-chain, funding the recovery from the backing wallet.

```ts
type ExitBatchOptions =
  | { mode: 'cooperative'; outpoints: string[]; destination?: string }
  | { mode: 'unilateral'; outpoints: string[]; confTarget?: number };
```

| Parameter                                          | Type      | Description                                                                                                                                                                         |
| -------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ mode: 'cooperative', outpoints, destination? }` | `variant` | Queues every outpoint into the next cooperative round. destination is optional; when omitted the daemon generates a fresh backing-wallet address per outpoint.                      |
| `{ mode: 'unilateral', outpoints, confTarget? }`   | `variant` | Forces every outpoint on-chain, funding the recovery from the backing wallet. confTarget is an optional confirmation target (in blocks) used to estimate fees for the funding plan. |

**`ExitBatchEvent`**

Progress events delivered to `exitBatch()`’s `onEvent` callback, in order, as it works through a batch.

```ts
type ExitBatchEvent =
  | { type: 'planned'; plan: GetExitPlanResult }
  | { type: 'starting'; outpoint: string }
  | { type: 'started'; outpoint: string; result: ExitResult }
  | { type: 'stopped'; stoppedBy: ExitBatchStop; remaining: string[] };
```

| Parameter                                   | Type      | Description                                                                        |
| ------------------------------------------- | --------- | ---------------------------------------------------------------------------------- |
| `{ type: 'planned', plan }`                 | `variant` | The latest unilateral funding plan from a re-plan round. Unilateral batches only.  |
| `{ type: 'starting', outpoint }`            | `variant` | Fires immediately before the exit() call for this outpoint.                        |
| `{ type: 'started', outpoint, result }`     | `variant` | Fires after exit() succeeds for this outpoint, carrying its ExitResult.            |
| `{ type: 'stopped', stoppedBy, remaining }` | `variant` | Fires once, when the batch halts before every outpoint started; see ExitBatchStop. |

**`ExitBatchStop`**

Why an `exitBatch()` run stopped before finishing every outpoint.

```ts
type ExitBatchStop =
  | { reason: 'infeasible'; plan: GetExitPlanResult }
  | { reason: 'rejected'; outpoint: string; error: Error };
```

| Parameter                                 | Type      | Description                                                                                                                                                   |
| ----------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{ reason: 'infeasible', plan }`          | `variant` | A re-plan reported the backing wallet can no longer fund the remaining exits. Unilateral batches only; plan is the GetExitPlanResult that triggered the stop. |
| `{ reason: 'rejected', outpoint, error }` | `variant` | An individual exit() call was rejected by the daemon for this outpoint.                                                                                       |

**`ExitBatchResult`**

The outcome of `exitBatch()`.

```ts
type ExitBatchResult = {
  started: { outpoint: string; result: ExitResult }[];
  skipped: string[];
  remaining: string[];
  stoppedBy?: ExitBatchStop;
};
```

| Parameter   | Type                                                         | Description                                                                                                                                |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `started`   | `{ outpoint: string, result: ExitResult }[]`                 | The exits successfully started. Each unilateral entry still runs for hours or days afterward; appearing here means started, not completed. |
| `skipped`   | `string[]`                                                   | Outpoints that already had a running exit job and were left alone rather than double-started.                                              |
| `remaining` | `string[]`                                                   | Outpoints never started, because the batch stopped early.                                                                                  |
| `stoppedBy` | [`ExitBatchStop`](/reference/wavelength-core/#ExitBatchStop) | Optional. Present when the batch halted before every outpoint started; see ExitBatchStop.                                                  |

## isExitInfeasibilityFundable

function

Distinguishes a fixable exit-infeasibility (the backing wallet needs more confirmed funds or inputs) from a structural one (the VTXO cannot be exited economically at all). Use it to decide whether to show a “fund your wallet” affordance or a terminal “cannot exit this VTXO” message. Mirrors the daemon’s own infeasibility split.

```ts
function isExitInfeasibilityFundable(
  reason: ExitInfeasibilityReason,
): boolean
```

| Parameter | Type                                                                             | Description                                                                                   |
| --------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `reason`  | [`ExitInfeasibilityReason`](/reference/wavelength-core/#ExitInfeasibilityReason) | The infeasibility reason from an ExitPlanEntry, typically read from a getExitPlan() response. |

Returns`boolean`

`true` for `wallet_underfunded` and `wallet_too_few_inputs` (funding the wallet resolves it); `false` for every other reason, including the structural `sweep_below_dust` and `uneconomical` blocks that no amount of funding fixes.

## sweepWallet

function

Previews or broadcasts a sweep of the backing wallet. Call it with `broadcast: false` first to preview; `broadcast: true` moves funds.

```ts
sweepWallet(req: SweepWalletRequest): Promise<SweepWalletResult>
```

| Parameter | Type                                                                   | Description                                       |
| --------- | ---------------------------------------------------------------------- | ------------------------------------------------- |
| `req`     | [`SweepWalletRequest`](/reference/wavelength-core/#SweepWalletRequest) | The destination and broadcast flag for the sweep. |

Returns`Promise<SweepWalletResult>`

The selected inputs, fees, and (on broadcast) the resulting txid.

**`SweepWalletRequest`**

```ts
type SweepWalletRequest = {
  destinationAddress: string;
  broadcast?: boolean;
  feeRateSatPerVByte?: number;
  confTarget?: number;
};
```

| Parameter            | Type      | Description                                                                            |
| -------------------- | --------- | -------------------------------------------------------------------------------------- |
| `destinationAddress` | `string`  | The on-chain address to sweep the backing wallet to.                                   |
| `broadcast`          | `boolean` | Optional. When true, broadcasts the sweep; when false (the default), only previews it. |
| `feeRateSatPerVByte` | `number`  | Optional. An explicit fee rate, in sat/vByte.                                          |
| `confTarget`         | `number`  | Optional. A confirmation target (in blocks) used to estimate fees.                     |

**`SweepWalletResult`**

```ts
type SweepWalletResult = {
  inputs: WalletSweepInput[];
  totalInputSat: number;
  estimatedFeeSat: number;
  netAmountSat: number;
  feeRateSatPerVByte: number;
  canBroadcast: boolean;
  txid: string;
  failureReason: string;
};
```

| Parameter            | Type                 | Description                                                                                   |
| -------------------- | -------------------- | --------------------------------------------------------------------------------------------- |
| `inputs`             | `WalletSweepInput[]` | The backing-wallet UTXOs selected for this sweep.                                             |
| `totalInputSat`      | `number`             | The combined amount of the selected inputs, in sats.                                          |
| `estimatedFeeSat`    | `number`             | The estimated fee, in sats.                                                                   |
| `netAmountSat`       | `number`             | The amount that will reach destinationAddress after fees, in sats.                            |
| `feeRateSatPerVByte` | `number`             | The fee rate used, in sat/vByte.                                                              |
| `canBroadcast`       | `boolean`            | Whether the sweep is currently valid to broadcast.                                            |
| `txid`               | `string`             | The broadcast transaction id. Populated only when broadcast was true and the sweep succeeded. |
| `failureReason`      | `string`             | A human-readable reason the sweep cannot broadcast, when canBroadcast is false.               |

**`WalletSweepInput`**

Describes one backing-wallet UTXO selected by `sweepWallet()`.

```ts
type WalletSweepInput = {
  outpoint: string;
  amountSat: number;
};
```

| Parameter   | Type     | Description               |
| ----------- | -------- | ------------------------- |
| `outpoint`  | `string` | The UTXO outpoint.        |
| `amountSat` | `number` | The UTXO amount, in sats. |

See the [leaving Ark guide](/concepts/leaving-ark/) for a walkthrough of the exit and sweep flow end to end.

## Portable facade calls

## callFacade

function

Invokes one portable mobile/wasm facade method. This is the low-level escape hatch for transport integrations; application code should prefer the typed methods documented above.

```ts
callFacade<T = unknown>(
  method: FacadeMethod,
  params?: unknown,
): Promise<T>
```

| Parameter | Type           | Description                                                                                    |
| --------- | -------------- | ---------------------------------------------------------------------------------------------- |
| `method`  | `FacadeMethod` | One of the portable facade method names listed below.                                          |
| `params`  | `unknown`      | Optional. The raw mobile/wasm request shape for that method, not the typed SDK request mapper. |

Returns`Promise<T>`

The response with normal SDK casing and method-aware null normalization, typed as `T` (unchecked; the caller asserts the shape).

**`FacadeMethod`**

```ts
type FacadeMethod =
  | 'start' | 'stop' | 'getInfo' | 'status' | 'balance'
  | 'createWallet' | 'unlockWallet' | 'openWalletFromPasskey'
  | 'deposit' | 'receive' | 'prepareSend' | 'sendPrepared'
  | 'list' | 'exit' | 'exitStatus' | 'exitSummary'
  | 'getExitPlan' | 'sweepWallet'
  | 'confirmedBalanceSat' | 'pendingInboundSat'
  | 'walletReady' | 'isRunning';
```

The whitelist excludes the streaming `subscribe` operation and private worker control methods such as `$ready` and `$init`. Requests use the raw mobile/wasm shapes, while responses use the same camelCase keys and schema-aware nil normalization as typed methods. The four scalar verbs `confirmedBalanceSat`, `pendingInboundSat`, `walletReady`, and `isRunning` are included for portable bridge callers.

> **Prefer the typed methods**
>
> Typed methods map SDK request shapes, validate relevant inputs, and return named results. Use `callFacade()` only when you specifically need the portable facade contract.

## camelizeKeys

function

Maps a daemon PascalCase JSON response onto the SDK’s camelCase shapes. The shared client applies this after transport invocation so typed methods and `callFacade()` return camelCase keys consistently across transports.

```ts
function camelizeKeys<T = unknown>(value: unknown): T
```

| Parameter | Type      | Description                                                |
| --------- | --------- | ---------------------------------------------------------- |
| `value`   | `unknown` | The raw daemon response (or any nested value) to camelize. |

Returns`T`

The same structure with every object key rewritten to camelCase. Arrays are walked recursively; primitives pass through unchanged.

## Runtime state model

## WalletState

const

Wallet lifecycle state returned in `WalletInfo.walletState`. The daemon sends a numeric enum; the SDK maps it to these lowercase strings at the response boundary via [`walletStateFromProto()`](#walletStateFromProto).

```ts
const WalletState = {
  None: 'none',
  Locked: 'locked',
  Ready: 'ready',
  Syncing: 'syncing',
} as const;

type WalletState = typeof WalletState[keyof typeof WalletState];
```

| Value     | Meaning                                                |
| --------- | ------------------------------------------------------ |
| `none`    | No wallet exists yet; one must be created.             |
| `locked`  | A wallet exists but is locked and must be unlocked.    |
| `ready`   | The wallet is unlocked and ready to use.               |
| `syncing` | The wallet is unlocked and catching up with the chain. |

## RuntimePhase

type

Lifecycle phase a UI renders. Runtime phases (`loading`, `runtimeReady`, `starting`, `stopping`, `stopped`, `error`) are owned by the host start/stop flow. Wallet phases (`needsWallet`, `locked`, `syncing`, `ready`) are derived from `WalletInfo` via [`phaseFromInfo()`](#phaseFromInfo). `restoring` is owned by the [`WalletEngine`](#WalletEngine) itself (like `starting`): it is never returned by `phaseFromInfo()`, and appears whenever an engine `restoreWallet()` call is in flight. When the call sets `recoverState: true`, the server-assisted recovery scan is additionally tracked through `snapshot.recovery`.

```ts
type RuntimePhase =
  | 'loading'
  | 'runtimeReady'
  | 'starting'
  | 'needsWallet'
  | 'locked'
  | 'syncing'
  | 'restoring'
  | 'ready'
  | 'stopping'
  | 'stopped'
  | 'error';
```

| Value          | Owner  | Meaning                                                                                                                                                                                |
| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loading`      | Host   | The runtime assets have not finished loading.                                                                                                                                          |
| `runtimeReady` | Host   | `ready()` resolved; the client is usable but the daemon has not started.                                                                                                               |
| `starting`     | Host   | `start()` has been called and has not yet resolved.                                                                                                                                    |
| `needsWallet`  | Wallet | No wallet exists yet (`WalletState.None`).                                                                                                                                             |
| `locked`       | Wallet | A wallet exists but is locked.                                                                                                                                                         |
| `syncing`      | Wallet | The wallet is unlocked and catching up with the chain.                                                                                                                                 |
| `restoring`    | Engine | A background restore (`WalletEngine.restoreWallet()`) is bringing a freshly restored wallet up; `recoverState: true` additionally tracks the recovery scan through the recovery state. |
| `ready`        | Wallet | The wallet is unlocked and ready (`walletReady` or `WalletState.Ready`).                                                                                                               |
| `stopping`     | Host   | `stop()` has been called and has not yet resolved.                                                                                                                                     |
| `stopped`      | Host   | The daemon has stopped.                                                                                                                                                                |
| `error`        | Host   | The host encountered an unrecoverable error starting or running the client.                                                                                                            |

## WalletPhase

type

The subset of lifecycle phases derived from wallet information by [`phaseFromInfo()`](#phaseFromInfo). Runtime-owned phases such as `starting` and `stopped` are represented by `RuntimePhase`, not this type.

```ts
type WalletPhase = 'needsWallet' | 'locked' | 'syncing' | 'ready';
```

## phaseFromInfo

function

Derives the wallet-state phase from a `WalletInfo`-shaped value. Runtime phases are not represented here; the caller owns those.

```ts
function phaseFromInfo(info: {
  walletState?: WalletState;
  walletReady?: boolean;
}): RuntimePhase
```

| Parameter          | Type                                                     | Description                                                                        |
| ------------------ | -------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `info.walletState` | [`WalletState`](/reference/wavelength-core/#WalletState) | Optional. The wallet lifecycle state to derive a phase from.                       |
| `info.walletReady` | `boolean`                                                | Optional. When true, short-circuits directly to 'ready' regardless of walletState. |

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

`'ready'` when `walletReady` is true or `walletState === 'ready'`; otherwise `'locked'` or `'syncing'` matching `walletState`; otherwise `'needsWallet'` (the fallback for `'none'` or any unrecognized value).

## normalizeInfo

function

Maps a raw daemon `Info` payload (numeric `walletState`, no `walletReady`) onto the public `WalletInfo`: converts `walletState` to the string union via [`walletStateFromProto()`](#walletStateFromProto) and backfills `walletReady` (ready iff `walletState === 'ready'`), mirroring the daemon’s `Info.WalletReady()` method. `BaseWavelengthClient` applies this through shared facade normalization after the transport returns the raw `getInfo()` result.

```ts
function normalizeInfo(raw: unknown): WalletInfo
```

| Parameter | Type      | Description                                    |
| --------- | --------- | ---------------------------------------------- |
| `raw`     | `unknown` | The raw daemon Info payload (untrusted shape). |

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

The normalized `WalletInfo`, with `walletState` as the SDK string union and `walletReady` backfilled if the raw payload did not already carry it.

## walletStateFromProto

function

Normalizes a raw daemon `walletState` (a proto number) to the SDK string union. Already-string values pass through unchanged.

```ts
function walletStateFromProto(
  value: number | WalletState | undefined,
): WalletState
```

| Parameter | Type                                 | Description                                                         |
| --------- | ------------------------------------ | ------------------------------------------------------------------- |
| `value`   | `number \| WalletState \| undefined` | The raw walletState as a proto number, an SDK string, or undefined. |

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

`'none'` when `value` is `undefined` or the proto zero value; the matching string for a recognized proto number (`1` → `'none'`, `2` → `'locked'`, `3` → `'ready'`, `4` → `'syncing'`); otherwise the conservative fallback `'locked'` for an unrecognized non-zero value (a future or garbled daemon state), so it never drives the UI into offering wallet creation over an existing wallet.

## Events and logging

## WavelengthEvent

type

Discriminated union of runtime events delivered to subscribers. Narrow on `type` to read the payload: `'activity'` carries the changed [`Entry`](#Entry), `'log'` carries a level and message, and the lifecycle events (`'runtimeReady'`, `'runtimeStopped'`) carry none. There are five event types: `runtimeReady`, `runtimeStopped`, `activity`, `activityStream`, and `log`.

```ts
type WavelengthEvent =
  | { type: 'runtimeReady' }
  | { type: 'runtimeStopped' }
  | { type: 'activity'; payload: Entry }
  | { type: 'activityStream'; payload: ActivityStreamPayload }
  | { type: 'log'; payload: WavelengthLogPayload };
```

| `type`           | Payload                 | Meaning                                                                 |
| ---------------- | ----------------------- | ----------------------------------------------------------------------- |
| `runtimeReady`   | (none)                  | The runtime finished loading.                                           |
| `runtimeStopped` | (none)                  | The daemon stopped, including an unsolicited stop from a worker crash.  |
| `activity`       | `Entry`                 | An activity entry changed; delivered while `startActivity()` is active. |
| `activityStream` | `ActivityStreamPayload` | The activity stream ended or failed without a consumer-initiated close. |
| `log`            | `WavelengthLogPayload`  | A daemon log line.                                                      |

Direct clients receive `activityStream` terminal events and choose their own retry policy. The event carries only `state` and, for failures, `message`. Structured gap cursor and reason details are not available through the current web and native bridges.

## ActivityStreamState

type

Whether an activity stream ended normally or failed unexpectedly. A consumer-initiated close emits no stream-status event.

```ts
type ActivityStreamState = 'ended' | 'failed';
```

## ActivityStreamPayload

type

The payload carried by an `activityStream` event. Narrow on `state` to access the failure message.

```ts
type ActivityStreamPayload =
  | { state: 'ended' }
  | { state: 'failed'; message: string };
```

## WavelengthEventType

type

The set of `WavelengthEvent` discriminants.

```ts
type WavelengthEventType = WavelengthEvent['type'];
```

## WavelengthListener

type

A subscriber callback invoked with each `WavelengthEvent`, passed to [`subscribe()`](#subscribe).

```ts
type WavelengthListener = (event: WavelengthEvent) => void;
```

## WavelengthLogPayload

type

The payload carried by a `'log'` event.

```ts
type WavelengthLogPayload = {
  level: WavelengthLogLevel;
  message: string;
};
```

| Parameter | Type                                                                   | Description                     |
| --------- | ---------------------------------------------------------------------- | ------------------------------- |
| `level`   | [`WavelengthLogLevel`](/reference/wavelength-core/#WavelengthLogLevel) | The severity of the log line.   |
| `message` | `string`                                                               | The human-readable log message. |

## WavelengthLogLevel

type

The severity of a `'log'` event emitted by the runtime.

```ts
type WavelengthLogLevel = 'debug' | 'info' | 'warn' | 'error';
```

| Value   | Meaning                                  |
| ------- | ---------------------------------------- |
| `debug` | Verbose diagnostic detail.               |
| `info`  | Normal operational messages.             |
| `warn`  | Recoverable but noteworthy conditions.   |
| `error` | Failures worth surfacing to a developer. |

## Errors

## WavelengthError

class

Base error class thrown by all Wavelength SDK packages. Carries a machine-readable `code` alongside the human-readable message.

```ts
class WavelengthError extends Error {
  readonly code: WavelengthErrorCode;
  constructor(message: string, code?: WavelengthErrorCode, options?: { cause?: unknown });
}
```

| Parameter       | Type                                                                     | Description                                                                                                                                                                        |
| --------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message`       | `string`                                                                 | Human-readable description of what went wrong.                                                                                                                                     |
| `code`          | [`WavelengthErrorCode`](/reference/wavelength-core/#WavelengthErrorCode) | Machine-readable error code. Defaults to wavelength\_error.                                                                                                                        |
| `options.cause` | `unknown`                                                                | Optional. The underlying error or value that caused this one, forwarded to the native Error cause chain (options.cause) so it survives in stack traces and error inspection tools. |

## WavelengthErrorCode

type

Stable, machine-readable error classification on `WavelengthError`. Named SDK codes are listed below; daemon-originated errors currently fall back to `wavelength_error`. The `(string & {})` arm keeps the union open for forward compatibility while still offering autocomplete on the known codes.

```ts
type WavelengthErrorCode =
  | 'wavelength_error'
  | 'runtime_not_ready'
  | 'asset_load_failed'
  | 'worker_error'
  | (string & {});
```

| Code                | Thrown when                                                                                                |
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
| `wavelength_error`  | The generic default: any SDK error without a more specific code, and all daemon-originated failures today. |
| `runtime_not_ready` | A method is called before `ready()` has resolved, or after `dispose()`.                                    |
| `asset_load_failed` | `ready()` fails to load the runtime assets (wasm binary or its supporting files).                          |
| `worker_error`      | The worker transport’s underlying Worker fails or crashes.                                                 |

## PasskeyCancelledError

class

Thrown by passkey ceremonies when the user dismisses the OS prompt, so hosts can suppress cancellation copy without string-matching the message. `wavelength-react`’s `useWalletPasskey` rethrows it without recording it into `createError`/`openError`.

```ts
class PasskeyCancelledError extends Error {
  constructor(message?: string);
}
```

| Parameter | Type     | Description                                             |
| --------- | -------- | ------------------------------------------------------- |
| `message` | `string` | Optional. Defaults to 'passkey ceremony was cancelled'. |

## toError

function

Normalizes an unknown thrown value to an `Error`, preserving an existing `Error` instance (and therefore its stack and `cause`) unchanged. Used throughout the SDK, including by every mutation hook’s throw-and-capture convention, to guarantee `error` fields are always `Error | null`, never a string or other thrown value.

```ts
function toError(value: unknown): Error
```

| Parameter | Type      | Description                                             |
| --------- | --------- | ------------------------------------------------------- |
| `value`   | `unknown` | The thrown value to normalize; may already be an Error. |

Returns`Error`

`value` unchanged if it is already an `Error`; otherwise a new `Error` built from it via `errorMessage()`.

## Passkeys

## WalletKind

type

Labels how a local wallet is unlocked.

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

| Value      | Meaning                                                                       |
| ---------- | ----------------------------------------------------------------------------- |
| `passkey`  | The wallet is unlocked by deriving key material from a passkey PRF assertion. |
| `password` | The wallet is unlocked with a plain password via `unlockWallet()`.            |

## PasskeyAssertion

type

A passkey ceremony result: the PRF output (hex) shared with the Go SDK, plus the credential id that produced it so callers can scope later assertions to the same passkey.

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

| Parameter      | Type     | Description                                                                                         |
| -------------- | -------- | --------------------------------------------------------------------------------------------------- |
| `prfOutput`    | `string` | The PRF output (hex) shared with the Go SDK. Pass this into OpenWalletFromPasskeyRequest.prfOutput. |
| `credentialId` | `string` | The credential id that produced the PRF output.                                                     |

## PasskeyCeremony

type

The per-platform passkey ceremony contract a host injects to drive [`openWalletFromPasskey()`](#openWalletFromPasskey). Injecting it keeps consumers of this contract free of any transport dependency: [`wavelength-web`](/reference/wavelength-web/) supplies the browser (WebAuthn/PRF) implementation as `webPasskeyCeremony`, and `wavelength-react`’s `useWalletPasskey` hook drives whichever implementation you pass it. The React Native transport supplies its own implementation, `createNativePasskeyCeremony` ([wavelength-react-native](/reference/wavelength-react-native/)).

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

| Parameter               | Type                                                        | Description                                                        |
| ----------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------ |
| `supportsPasskeyPrf`    | `() => Promise<boolean>`                                    | Resolves true when the platform supports passkey PRF.              |
| `registerPasskeyWallet` | `(appName: string) => Promise<PasskeyAssertion>`            | Registers a new passkey wallet and returns its assertion.          |
| `assertPasskeyPrf`      | `(allowCredentialId?: string) => Promise<PasskeyAssertion>` | Asserts an existing passkey, optionally scoped to a credential id. |
