---
title: "wavelength-web"
description: "Browser SDK factory, configuration, and passkey ceremony API for Wavelength web apps."
canonical: https://wavelength.lightning.engineering/reference/wavelength-web/
---

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

# wavelength-web

Browser SDK factory, configuration, and passkey ceremony API for Wavelength web apps.

`@lightninglabs/wavelength-web` is the browser/wasm transport for the Wavelength SDK: it runs the embedded daemon as WebAssembly, either in a dedicated Web Worker (the default) or on the page’s main thread, and exposes it as a standard [`WavelengthClient`](/reference/wavelength-core/#WavelengthClient). `createWebWalletEngine()` wraps that client in a [`WalletEngine`](/reference/wavelength-core/#WalletEngine) in one call, which is the entry point most apps want. It also ships the browser (WebAuthn/PRF) passkey ceremony.

> **One import for the client and every type**
>
> This package re-exports the entire [`@lightninglabs/wavelength-core`](/reference/wavelength-core/) public surface (`export * from '@lightninglabs/wavelength-core'`). You only need to import from `@lightninglabs/wavelength-web` to get the client factory, every request/result and nested response type, every core-exported generated string-enum constant, and `defaultConfig()`. This includes `FacadeMethod`, `ActivityStreamOptions`, `EntryProgress`, `CreditPreview`, and the complete activity, list, send, and exit type families. There is no need to also depend on `@lightninglabs/wavelength-core` directly.

## Configuration

## defaultConfig

function

Returns a ready-to-use `RuntimeConfig` for a network, preloaded with the canonical public REST gateway endpoints the web transport dials, merged with any overrides. This is a shallow merge of top-level `RuntimeConfig` fields. Pass overrides to set `dataDir` or point at your own infrastructure.

```ts
function defaultConfig(
  network: PresetNetwork,
  overrides?: Partial<RuntimeConfig>,
): RuntimeConfig
```

| Parameter   | Type                     | Description                                                                                                                               |
| ----------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `network`   | `PresetNetwork`          | The Bitcoin network to run against; mainnet and regtest are excluded because they have no preset. Use signet for development and testing. |
| `overrides` | `Partial<RuntimeConfig>` | Optional. Fields that override the network preset's defaults. Default: {}.                                                                |

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

A complete configuration object for `client.start()` or the engine factory’s `config`.

```ts
import { defaultConfig } from '@lightninglabs/wavelength-web';

const config = defaultConfig('signet', { dataDir: 'my-wallet' });
```

`'mainnet'` and `'regtest'` are not accepted: mainnet has no public deployment yet, and regtest’s local ports vary per development environment. Build their `RuntimeConfig` by hand, mainnet with your own gateway URLs and `allowMainnet`, regtest with local URLs and the insecure-transport flags. On web, `arkServerAddress` and `swapServerAddress` are REST URLs, and `walletEsploraUrl` is an HTTP Esplora endpoint. The web transport rejects `arkServerTlsCertPath`. It accepts `swapServerTlsCertPath` only when `disableSwaps: true`, which suppresses every swap field. The per-network endpoint values are on the [wavelength-core reference](/reference/wavelength-core/#Network).

## Creating a client

## createWebClient

function

Creates and returns a `WavelengthClient` that runs the embedded daemon in the browser. Call once at application startup, then wrap it with [`createWalletEngine`](/reference/wavelength-core/#createWalletEngine) from `@lightninglabs/wavelength-core` (or use [`createWebWalletEngine`](#creating-an-engine) below to do both in one call) or call `start(defaultConfig(network))` directly. Defaults to the Web Worker transport ([`WorkerWavelengthClient`](#transports)); pass `runtimeThread: 'main'` to run on the page’s main thread instead.

```ts
function createWebClient(
  options?: WebClientOptions,
): WavelengthClient
```

| Parameter | Type                                                              | Description                                                                                           |
| --------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `options` | [`WebClientOptions`](/reference/wavelength-web/#WebClientOptions) | Optional browser-specific settings. Defaults to worker-thread mode with page-relative runtime assets. |

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

A live client instance. Call `ready()` to wait for the WASM runtime to load, then `start(config)` to boot the daemon.

## WebClientOptions

type

Browser-specific options for `createWebClient`. The config passed to `client.start()` is separate: use `defaultConfig(network)` from `@lightninglabs/wavelength-web`.

```ts
type WebClientOptions = {
  workerURL?: string;
  runtimeBaseUrl?: string;
  runtimeThread?: RuntimeThread;
  debug?: boolean;
};
```

| Parameter        | Type                                                        | Description                                                                                                                                                                                                                                                                                                                   |
| ---------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `workerURL`      | `string`                                                    | Overrides the worker entry point. By default the worker client spawns the worker its bundler emits from new URL("./wavewalletdk-worker.js", import.meta.url); pass this to point at a custom-hosted copy instead. runtimeBaseUrl is still forwarded to the worker even when this is set. Default: bundler-emitted worker URL. |
| `runtimeBaseUrl` | `string`                                                    | Base URL the daemon runtime binaries (wavewalletdk.wasm.gz, wasm\_exec.js, sqlite-\*.js) are resolved against. Unset resolves relative to the document: worker mode computes the document base URL and forwards it to the worker so it resolves page-relative just like main-thread mode. Default: unset (page-relative).     |
| `runtimeThread`  | [`RuntimeThread`](/reference/wavelength-web/#RuntimeThread) | Which thread runs the WASM runtime. 'main' produces a MainThreadWavelengthClient that blocks rendering while busy; use it only when Worker support is unavailable. Default: 'worker'.                                                                                                                                         |
| `debug`          | `boolean`                                                   | Logs every RPC request and response payload to the console. Payloads can include addresses and amounts, so treat this as a development-only aid and never enable it in a shipped app. Main-thread mode logs facade calls directly; worker mode forwards the flag into the worker so it can log there too. Default: false.     |

## RuntimeThread

type

Selects which thread the wasm runtime runs on: `'worker'` (default) in a dedicated Web Worker that keeps the UI thread free, or `'main'` on the page’s main thread as an escape hatch (for example, environments without Worker support).

```ts
type RuntimeThread = 'main' | 'worker';
```

## Creating an engine

## createWebWalletEngine

function

Creates a [`WalletEngine`](/reference/wavelength-core/#WalletEngine) over the browser/wasm transport: the one-call setup for a web app. It builds the client with `createWebClient()` internally, so you only need this one factory. Pass the result to `WavelengthProvider` from [wavelength-react](/reference/wavelength-react/), or drive it directly without React.

```ts
function createWebWalletEngine(
  options?: WebWalletEngineOptions,
): WalletEngine
```

| Parameter | Type                                                                          | Description                                                                                              |
| --------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `options` | [`WebWalletEngineOptions`](/reference/wavelength-web/#WebWalletEngineOptions) | Optional. The same browser-specific settings as createWebClient, plus the engine's config and autoStart. |

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

A live engine driving a freshly built web client. See [`WalletEngine`](/reference/wavelength-core/#WalletEngine) for its full behavior, including the background processes it runs automatically.

**`WebWalletEngineOptions`**

The browser-specific settings from `WebClientOptions` combined with [`WalletEngineOptions`](/reference/wavelength-core/#createWalletEngine)’s config/autoStart union (minus `client`, which this factory builds for you): the types require a config when autoStart is enabled, so `autoStart: true` without `config` is a compile error.

```ts
type WebWalletEngineOptions = WebClientOptions &
  (
    | { config: RuntimeConfig; autoStart: true }
    | { config?: RuntimeConfig; autoStart?: false }
  );
```

| Parameter        | Type                                                         | Description                                                                                                                         |
| ---------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `workerURL`      | `string`                                                     | Same as WebClientOptions.workerURL.                                                                                                 |
| `runtimeBaseUrl` | `string`                                                     | Same as WebClientOptions.runtimeBaseUrl.                                                                                            |
| `runtimeThread`  | [`RuntimeThread`](/reference/wavelength-web/#RuntimeThread)  | Same as WebClientOptions.runtimeThread.                                                                                             |
| `debug`          | `boolean`                                                    | Same as WebClientOptions.debug.                                                                                                     |
| `config`         | [`RuntimeConfig`](/reference/wavelength-core/#RuntimeConfig) | Required when autoStart is true. Default runtime config used by autoStart and by the engine's start() when called with no argument. |
| `autoStart`      | `true \| false`                                              | Optional. Start the runtime automatically once it is ready. Setting it to true requires config.                                     |

```tsx
import { createWebWalletEngine, defaultConfig } from '@lightninglabs/wavelength-web';
import { WavelengthProvider } from '@lightninglabs/wavelength-react';

const engine = createWebWalletEngine({
  runtimeBaseUrl: 'https://your-host/wavewalletdk/',
  config: defaultConfig('signet'),
  autoStart: true,
});

export function Root() {
  return <WavelengthProvider engine={engine}>{/* your app */}</WavelengthProvider>;
}
```

## Transports

## MainThreadWavelengthClient

class

Runs the wasm runtime on the page’s main thread. It implements [`WavelengthClient`](/reference/wavelength-core/#WavelengthClient) directly and is the escape hatch for environments without Web Worker support (or where main-thread execution is preferred for another reason). Unlike worker mode it blocks rendering while the runtime is busy.

```ts
class MainThreadWavelengthClient implements WavelengthClient {
  constructor(options?: WebClientOptions);
}
```

| Parameter | Type                                                              | Description                                                                                                                  |
| --------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `options` | [`WebClientOptions`](/reference/wavelength-web/#WebClientOptions) | Same options accepted by createWebClient. runtimeThread is ignored here since the constructor already picks the main thread. |

Prefer `createWebClient({ runtimeThread: 'main' })` over constructing this class directly; only reach for the class import when you need to branch construction logic yourself (for example, feature-detecting Worker support at runtime).

`WorkerWavelengthClient` is the default transport returned by `createWebClient()` (when `runtimeThread` is unset or `'worker'`). It is not exported directly, select it via `createWebClient()`. Worker mode requires a daemon that stores the encrypted seed in OPFS rather than `localStorage` (which is window-only and unavailable inside a Worker); the daemon shipped with this package already does this. See the [browser support guide](/web/support/browser-support/) for which browsers provide OPFS and the other APIs worker mode depends on.

## Runtime assets and hosting

## RUNTIME\_ASSETS

const

The canonical set of daemon runtime binaries the wasm client loads at runtime, resolved against `runtimeBaseUrl`. `RUNTIME_ASSET_FILES` is just `Object.values(RUNTIME_ASSETS)`. This set is built by wavelength (`make wasm-wallet`) and version-locked to the embedded wavelength daemon, so the files must be hosted side by side at one base URL.

```ts
const RUNTIME_ASSETS: {
  wasm: string;
  wasmGz: string;
  wasmExec: string;
  sqliteBridge: string;
  sqliteWorker: string;
  sqlite: string;
  sqliteWasm: string;
  sqliteOpfsProxy: string;
};
```

The values are fixed filenames, not just string-typed placeholders:

| Key               | Filename                      |
| ----------------- | ----------------------------- |
| `wasm`            | `wavewalletdk.wasm`           |
| `wasmGz`          | `wavewalletdk.wasm.gz`        |
| `wasmExec`        | `wasm_exec.js`                |
| `sqliteBridge`    | `sqlite-bridge.js`            |
| `sqliteWorker`    | `sqlite-worker.js`            |
| `sqlite`          | `sqlite3.js`                  |
| `sqliteWasm`      | `sqlite3.wasm`                |
| `sqliteOpfsProxy` | `sqlite3-opfs-async-proxy.js` |

## RUNTIME\_ASSET\_FILES

const

Flat list of every runtime binary that must be hosted together at `runtimeBaseUrl`: `wavewalletdk.wasm`, `wavewalletdk.wasm.gz`, `wasm_exec.js`, `sqlite-bridge.js`, `sqlite-worker.js`, `sqlite3.js`, `sqlite3.wasm`, `sqlite3-opfs-async-proxy.js` (that is, `Object.values(RUNTIME_ASSETS)`). Host these files and point `runtimeBaseUrl` at them before calling `client.ready()`.

```ts
const RUNTIME_ASSET_FILES: readonly string[];
```

## RUNTIME\_MANIFEST\_VERSION

const

The daemon build this SDK release is paired with: the generated types, the client methods, and the runtime asset set all come from this one daemon revision. Hosted asset sets live in a directory named after this value, so a version bump changes every asset URL and browsers can never serve a stale cached runtime. Defined in (and re-exported from) `@lightninglabs/wavelength-core`.

```ts
const RUNTIME_MANIFEST_VERSION: string;
```

### Asset resolution and loading

`runtimeBaseUrl` controls where each file in `RUNTIME_ASSETS` is fetched from:

- **Trailing slash:** a base URL is normalized by appending a trailing slash if missing before resolving each asset name against it, so `https://assets.example.com/wavewalletdk` and `https://assets.example.com/wavewalletdk/` behave the same.
- **Unset base:** with no `runtimeBaseUrl`, the bare filename is used and resolves relative to the document. In worker mode the worker cannot resolve page-relative paths itself, so the client computes the document’s base URL (`document.baseURI`) on the main thread and forwards it to the worker as part of its `$init` message, keeping worker mode and main-thread mode page-relative in the same way.
- **Compressed-first wasm loading:** the client prefers the gzip-compressed `wavewalletdk.wasm.gz` binary, inflating it through a `DecompressionStream` and instantiating the resulting bytes, when the browser supports `DecompressionStream`. If that path fails (or the API is unavailable), it falls back to fetching the uncompressed `wavewalletdk.wasm` and instantiating it via `WebAssembly.instantiateStreaming`.
- **Streaming-to-ArrayBuffer fallback:** `instantiateStreaming` requires the server to serve the wasm response with an `application/wasm` content type. If the host is misconfigured and omits it, streaming instantiation throws and the client retries by reading the same response into an `ArrayBuffer` and calling `WebAssembly.instantiate` on the bytes directly, so a misconfigured MIME type does not break self-hosted runtimes.
- **Worker entry resolution:** the worker script itself (unlike the daemon binaries above) ships inside `@lightninglabs/wavelength-web` and is emitted by your bundler via `new URL('../wavewalletdk-worker.js', import.meta.url)`, so it versions with the SDK and needs no separate hosting. `runtimeBaseUrl` is still forwarded to the worker (via its `$init` message) even when you override the worker entry point with `workerURL`, since the two settings are independent: `workerURL` only changes where the worker script itself loads from.

See the [hosting runtime assets guide](/web/get-started/hosting-runtime-assets/) for a complete self-hosting walkthrough.

## Passkeys (browser)

## webPasskeyCeremony

const

Browser (WebAuthn/PRF) implementation of the [`PasskeyCeremony`](/reference/wavelength-core/#PasskeyCeremony) contract. It is literally the three standalone functions below grouped into one object; pass it to `useWalletPasskey` from wavelength-react, or call the functions directly.

```ts
const webPasskeyCeremony: PasskeyCeremony;
```

```ts
const webPasskeyCeremony: PasskeyCeremony = {
  supportsPasskeyPrf,
  registerPasskeyWallet,
  assertPasskeyPrf,
};
```

## supportsPasskeyPrf

function

Reports whether a user-verifying platform authenticator is available, which is a prerequisite for WebAuthn PRF.

```ts
function supportsPasskeyPrf(): Promise<boolean>;
```

Returns`Promise<boolean>`

`true` when a platform authenticator that can perform user verification is available.

> **Not a guarantee**
>
> `supportsPasskeyPrf() === true` does not guarantee the PRF ceremony will succeed. There is no synchronous PRF-detection API, so a browser can report `true` here yet still fail to return a PRF result during `registerPasskeyWallet` or `assertPasskeyPrf`. Always handle rejection from those calls even after a `true` check.

## registerPasskeyWallet

function

Creates a new platform passkey and returns its PRF output and credential id. Some browsers do not surface the PRF result from `create()`, so this falls back to an assertion scoped to the just-created credential to read it reliably without prompting a chooser.

```ts
function registerPasskeyWallet(
  appName: string,
): Promise<PasskeyAssertion>;
```

| Parameter | Type     | Description                                                                                                           |
| --------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
| `appName` | `string` | Used as both the WebAuthn relying-party name (rp.name) and the account display name shown by the platform passkey UI. |

Returns`Promise<PasskeyAssertion>`

The new credential’s PRF output and credential id. Rejects if registration is cancelled.

## assertPasskeyPrf

function

Authenticates with a passkey and returns its PRF output plus the credential id used.

```ts
function assertPasskeyPrf(
  allowCredentialId?: string,
): Promise<PasskeyAssertion>;
```

| Parameter           | Type     | Description                                                                                                                                                                                                                                                                                                                                     |
| ------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowCredentialId` | `string` | Optional. When set, the assertion is scoped to that one credential (base64url id from a prior PasskeyAssertion.credentialId) so the OS unlocks it directly without a chooser. When omitted, the assertion is discoverable (an empty allowCredentials list) so a synced passkey can be offered even on a device that has never seen this wallet. |

Returns`Promise<PasskeyAssertion>`

The asserted credential’s PRF output and credential id. Rejects if authentication is cancelled.

## PasskeyAssertion

type

Result of a passkey registration or assertion ceremony. Defined in [`@lightninglabs/wavelength-core`](/reference/wavelength-core/#PasskeyAssertion) and surfaced here through the re-export (see the callout at the top of this page); shown in full because it is the return type of the two functions above.

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

| Parameter      | Type     | Description                                                                                                                                                         |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prfOutput`    | `string` | The WebAuthn PRF extension output, as a lower-case hex string.                                                                                                      |
| `credentialId` | `string` | The base64url-encoded WebAuthn credential id. Safe to persist and pass back into assertPasskeyPrf(allowCredentialId) to scope a later assertion to this credential. |

**Reproducibility.** Both functions evaluate the PRF extension against a fixed salt, `SHA-256("wavewalletdk-passkey:v1")`, a fixed namespace chosen client-side. Using the same fixed salt on every device/platform is what makes the derived wallet reproducible: asserting the same passkey anywhere yields the same `prfOutput`, and therefore the same derived wallet.

**Discoverable vs. scoped assertions.** `assertPasskeyPrf()` called with no argument performs a *discoverable* assertion (empty `allowCredentials`), letting the platform’s passkey chooser surface any matching synced passkey, including on a device that has never seen this wallet before. Passing `allowCredentialId` instead performs a *scoped* assertion limited to that one credential, which lets the OS unlock it directly without showing a chooser.

## Re-exported from wavelength-core

Types like `SendRequest` and `ReceiveRequest` referenced by [`WavelengthClient`](/reference/wavelength-core/#WavelengthClient) methods (`send`, `prepareSend`, `receive`, and so on) originate in [`@lightninglabs/wavelength-core`](/reference/wavelength-core/) and are available here only because `wavelength-web` re-exports the entire core package (see the callout at the top of this page). The `.d.ts` filename shown in each signature below is illustrative of the shape, not of which package physically declares the type.

## SendRequest

type

Parameters accepted by `prepareSend()` and `send()`. `SendRequest` is a discriminated union: provide `invoice` for a Lightning send, or `onchainAddress` for an on-chain send. The two branches are mutually exclusive; `sweepAll` exists only on the on-chain branch.

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

| Parameter        | Type      | Description                                                                                                |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| `invoice`        | `string`  | BOLT11 lightning invoice to pay. Mutually exclusive with onchainAddress.                                   |
| `onchainAddress` | `string`  | Bech32 Bitcoin address for an on-chain send. Mutually exclusive with invoice.                              |
| `amountSat`      | `number`  | Required at runtime for on-chain sends unless sweepAll is true; the TypeScript type does not enforce this. |
| `note`           | `string`  | Optional memo stored with the activity entry.                                                              |
| `maxFeeSat`      | `number`  | Optional fee ceiling for the send.                                                                         |
| `sweepAll`       | `boolean` | Drain every live VTXO to onchainAddress. Only present on the on-chain branch.                              |

## ReceiveRequest

type

Parameters accepted by `receive()`.

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

| Parameter   | Type     | Description                                   |
| ----------- | -------- | --------------------------------------------- |
| `amountSat` | `number` | Invoice amount in satoshis.                   |
| `memo`      | `string` | Optional description embedded in the invoice. |

## See also

- [wavelength-core reference](/reference/wavelength-core/) for `WavelengthClient`, `WalletEngine`, `RuntimeConfig`, `WalletInfo`, `Balance`, `Entry`, and every other re-exported type.
- [wavelength-react reference](/reference/wavelength-react/) for `WavelengthProvider` and the hooks that consume an engine created here.
- [Hosting runtime assets](/web/get-started/hosting-runtime-assets/) for a full self-hosting walkthrough of the files listed above.
