Quickstart (React)

Install

Install the two packages you need: wavelength-web for the browser wallet runtime and wavelength-react for the React bindings.

Terminal window
npm install @lightninglabs/wavelength-web @lightninglabs/wavelength-react

Requires Node 20 or later to run locally. The runtime itself runs in Chrome 100+, Firefox 110+, and Safari 16+. No special build config is needed for Vite or Next.js.

Wire the provider

Create a WalletEngine with createWebWalletEngine(), and wrap your app with WavelengthProvider. Pass config and autoStart: true to boot the embedded daemon as soon as the runtime is ready, no boot effect needed. Every component below the provider gains access to the wallet through hooks.

App.tsx
import { createWebWalletEngine, defaultConfig } from '@lightninglabs/wavelength-web';
import { WavelengthProvider, useWallet } from '@lightninglabs/wavelength-react';
const engine = createWebWalletEngine({
runtimeBaseUrl: '/wavewalletdk/',
config: defaultConfig('signet'),
autoStart: true,
});
export function App() {
return (
<WavelengthProvider engine={engine}>
<Balance />
<SendButton />
</WavelengthProvider>
);
}
function Balance() {
const { phase } = useWallet();
return <p>Wallet phase: {phase}</p>;
}

defaultConfig(network, overrides?) returns a RuntimeConfig preloaded with public REST gateway endpoints for that network. Overrides are a shallow merge, so pass only top-level fields such as dataDir. Keep this quickstart on the default config path; see Networks & config for advanced self-hosting fields.

mainnet has no preset: build its RuntimeConfig by hand with allowMainnet: true, and only after you have key-backup UX in place. Mainnet access is also gated to an approved allowlist; see Mainnet access.

Create a wallet

Call create from useWalletCreate to generate a new HD seed in the browser. The seed is encrypted locally and never transmitted.

Onboard.tsx
import { useWalletCreate } from '@lightninglabs/wavelength-react';
function Onboard() {
const { create, createPending } = useWalletCreate();
const handleCreate = async () => {
const { mnemonic } = await create({ password: 'a-strong-password' });
// Back up `mnemonic` securely before the user sends funds.
console.log('Wallet created');
};
return (
<button onClick={handleCreate} disabled={createPending}>
Create wallet
</button>
);
}

Once create resolves, phase from useWallet automatically advances (through 'syncing' when the daemon needs to catch up) to 'ready', so any component watching phase updates without extra wiring.

Try it

Call send from useWalletSend with a Lightning invoice or on-chain address. Wavelength routes Lightning payments through the swap server and settles on-chain sends through a cooperative leave with the Ark operator.

SendButton.tsx
import { useWalletSend } from '@lightninglabs/wavelength-react';
function SendButton() {
const { send, sendPending } = useWalletSend();
const handleSend = async () => {
const result = await send({
invoice: 'lnbc1…', // or onchainAddress: 'bc1q…'
});
console.log('Sent!', result.paymentHash ?? result);
};
return (
<button onClick={handleSend} disabled={sendPending}>
Send
</button>
);
}

You are all set. Explore the full guides to go deeper on individual topics.