---
title: "What is the Wavelength SDK?"
description: "An overview of the Wavelength SDK as a self-custodial Bitcoin, Lightning, and Ark wallet that embeds in your web or mobile app."
canonical: https://wavelength.lightning.engineering/introduction/what-is-wavelength-sdk/
---

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

# What is the Wavelength SDK?

## What it is

The Wavelength SDK is a TypeScript library for embedding a **self-custodial Bitcoin, Lightning, and Ark wallet** directly in your web or mobile app. Your users hold their own keys. You do not run a wallet server on their behalf. (Building a pure-native Kotlin or Swift app? The same embedded wallet ships as a [native mobile SDK](/native-ios-android/overview/) too.)

The full wallet daemon ([wavelength](https://github.com/lightninglabs/wavelength)) is compiled to run **inside your app**: to WebAssembly in the browser on web, and into the app binary on mobile. There is no separate process, no local socket, and no backend you must operate to host the wallet logic. Your app boots the daemon and talks to it through a typed client.

The Wavelength SDK ships as these packages:

Package

`@lightninglabs/wavelength-core`

Role

Shared types, the WavelengthClient interface, errors, and enums. No DOM, no transport.

Package

`@lightninglabs/wavelength-web`

Role

The browser WASM transport. Framework-agnostic: use it from vanilla JS, Vue, Svelte, or React. Re-exports core.

Package

`@lightninglabs/wavelength-react-native`

Role

The React Native transport. The daemon is compiled into the app binary. Re-exports core.

Package

`@lightninglabs/wavelength-react`

Role

React provider and hooks. Depends on core only and takes an injected client, so the same binding can run over the web or React Native transport.

**React is the primary developer experience**, but React is not required. On web, if you are not using React, install `@lightninglabs/wavelength-web`, call `createWebClient()`, and use the `WavelengthClient` methods directly. The React package is a thin binding over the same interface.

Native iOS and Android apps are covered as well: the [wavelength-mobile](https://github.com/lightninglabs/wavelength-mobile) wrappers embed the same daemon behind idiomatic Kotlin and Swift APIs, documented in the [Native iOS & Android](/native-ios-android/overview/) section.

## Mental model

Think of the Wavelength SDK as **your app talking to a local wallet daemon**, not your app talking to a remote wallet API.

Your app

WavelengthClienttyped API

Embedded daemonin your app

GatewaysArk · Swap · Esplora

1. **Your app** calls methods like `balance()`, `send()`, and `deposit()` on a `WavelengthClient`.
2. **The client** forwards those calls to the embedded daemon running in your app (on web, in a Web Worker by default, or the main thread if configured).
3. **The daemon** holds keys, tracks VTXOs, coordinates Ark rounds, and reaches out to public infrastructure when it needs chain data, mailbox relay, or Lightning swaps.

The daemon connects to three backend services configured in `RuntimeConfig`:

- **Ark operator + mailbox** (`arkServerAddress`) for rounds and VTXO/mailbox relay
- **Swap server** (`swapServerAddress`) for Lightning↔Ark atomic swaps
- **Esplora** (`walletEsploraUrl`) for chain and UTXO queries

On web, the Ark and swap addresses are REST URLs. On React Native, they are `host:port` gRPC addresses. `walletEsploraUrl` is an HTTP Esplora endpoint on both platforms.

Your app never calls those gateways directly. It only talks to the local daemon. **User keys never leave the device.** Seed generation, signing, and wallet state live on the device (OPFS in the browser; the app data directory on React Native). The gateways see protocol traffic, not your users’ private keys.

A minimal boot sequence looks like this:

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

const client = createWebClient({ runtimeBaseUrl: '/wavewalletdk/' });

await client.ready();                        // load WASM runtime
await client.start(defaultConfig('signet')); // boot daemon, connect gateways
const { mnemonic } = await client.createWallet({ password: '…' }); // show mnemonic to the user for backup
```

```ts
import { createNativeClient, defaultConfig } from '@lightninglabs/wavelength-react-native';

const client = createNativeClient();

await client.ready();                        // ready the native runtime
await client.start(defaultConfig('signet')); // boot daemon, connect gateways
const { mnemonic } = await client.createWallet({ password: '…' }); // show mnemonic to the user for backup
```

From here, use the same client for deposits, Lightning receive, sends, and activity. The [System architecture](/introduction/system-architecture/) page explains how those operations map to Ark, swaps, and on-chain exits.
