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 or wavelength-react-native’s defaultConfig instead.

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

wavelength-core.d.ts
function networkDefaults(
network: PresetNetwork,
transport: ServerTransport,
): Partial<RuntimeConfig>
networkPresetNetwork
The Bitcoin network to look up; mainnet and regtest are excluded because they have no preset.
transportServerTransport
The endpoint flavor the caller's transport dials: 'rest' or 'grpc'.
ReturnsPartial<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'.

wavelength-core.d.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.

wavelength-core.d.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:

const config: RuntimeConfig = {
network: 'signet',
walletType: 'btcwallet',
walletFeeUrl: 'https://fees.example.com',
walletBlockHeadersSource: 'neutrino',
walletFilterHeadersSource: 'neutrino',
walletRecoveryWindow: 250,
maxOperatorFeeSat: 100,
signingWorkers: 4,
bufferSize: 64,
};
networkNetwork
The Bitcoin network to run against. Use mainnet only together with allowMainnet.
allowMainnetboolean
Must be true to run on mainnet. The SDK rejects a mainnet config without it before startup.
dataDirstring
Storage root for daemon and wallet state (an OPFS path in the browser). A daemon default is used when unset.
debugLevelstring
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.
arkServerAddressstring
Ark operator and mailbox endpoint. Use a REST URL on web and a host:port gRPC address on React Native.
arkServerTlsCertPathstring
Optional filesystem TLS certificate path for native transports. The web transport rejects it.
arkServerInsecureboolean
Disables TLS for the Ark endpoint. Use only for local development.
walletType'lwwallet' | 'btcwallet'
Embedded wallet backend. Default: lwwallet.
walletEsploraUrlstring
HTTP Esplora endpoint for lwwallet only, on both platforms.
walletPasswordFilestring
Password file for lwwallet only.
walletPollIntervalSecondsnumber
Chain polling interval for lwwallet only. Must be a nonnegative safe integer.
walletRecoveryWindownumber
Wallet address look-ahead window for either supported embedded backend. Must fit in uint32.
walletFeeUrlstring
Fee estimator endpoint for btcwallet only.
walletBlockHeadersSourcestring
Block-header source for btcwallet only.
walletFilterHeadersSourcestring
Compact-filter-header source for btcwallet only.
swapServerAddressstring
Swap endpoint. Use a REST URL on web and a host:port gRPC address on React Native.
swapServerTlsCertPathstring
Optional filesystem TLS certificate path for native transports. The web transport rejects it unless swaps are disabled.
swapServerInsecureboolean
Disables TLS for the swap endpoint. Use only for local development.
swapDatabaseFileNamestring
Daemon-owned SQLite file for swap state.
disableSwapsboolean
Disables Lightning swaps and suppresses preset and override swap fields.
maxOperatorFeeSatnumber
Maximum operator fee in satoshis. Must be a nonnegative safe integer.
signingWorkersnumber
Signing worker count. Must be a nonnegative safe integer.
bufferSizenumber
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.

Some daemon-only options (such as the LND wallet backend) are deliberately not exposed through RuntimeConfig. 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. testnet4 is part of the union and carries a preset, but its deployment is not supported yet, so its endpoints are not listed below.

wavelength-core.d.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):

signet
arkServerAddress
https://signet.wavelength-rest.lightning.finance
walletEsploraUrl
https://mempool-signet.testnet.lightningcluster.com/api
swapServerAddress
https://signet.swapd-rest.lightning.finance
testnet
arkServerAddress
https://test.wavelength-rest.lightning.finance
walletEsploraUrl
https://mempool-testnet3.testnet.lightningcluster.com/api
swapServerAddress
https://test.swapd-rest.lightning.finance
mainnet

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

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.

wavelength-core.d.ts
type ServerTransport = 'rest' | 'grpc';

MobileConfig

type

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

wavelength-core.d.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;
};

The daemon’s start verb accepts this lower-level shape; the SDK builds it from your RuntimeConfig when you call client.start(config). The lifecycle verbs are not reachable through callFacade, which rejects 'start' and 'stop' so the cross-tab runtime lock is never bypassed.

Client lifecycle

WavelengthClient

type

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

wavelength-core.d.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().

wavelength-core.d.ts
ready(): Promise<void>
ReturnsPromise<void>

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

start

function

Starts the embedded daemon with the given config and resolves with its initial WalletInfo. Calling start() while a session is already running coalesces onto it and resolves with the current info; the passed config is ignored, so call stop() first to start under a different one.

wavelength-core.d.ts
start(config: RuntimeConfig): Promise<WalletInfo>
configRuntimeConfig
The runtime configuration to start the daemon with. Build it with your transport package's defaultConfig(network) plus any overrides.
ReturnsPromise<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).

wavelength-core.d.ts
stop(): Promise<void>
ReturnsPromise<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() and, for the worker transport, terminates the underlying Worker. The client is unusable afterward; construct a new one to start again.

wavelength-core.d.ts
dispose(): void
Returnsvoid

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(), or reach for a transport’s own factory (createWebWalletEngine() from wavelength-web, createNativeWalletEngine() from wavelength-react-native), which builds the client for you. Pass the engine to WavelengthProvider from 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.

wavelength-core.d.ts
function createWalletEngine(options: WalletEngineOptions): WalletEngine
optionsWalletEngineOptions
The client to drive, plus optional default config and autoStart.
ReturnsWalletEngine

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.

wavelength-core.d.ts
type WalletEngineOptions =
{ onPerformance?: WavelengthPerformanceListener } & (
| { client: WavelengthClient; config: RuntimeConfig; autoStart: true }
| { client: WavelengthClient; config?: RuntimeConfig; autoStart?: false }
);
clientWavelengthClient
The transport client the engine drives.
configRuntimeConfig
Required when autoStart is true. Default runtime config used by autoStart and by start() when called with no argument.
autoStarttrue | 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.
onPerformanceWavelengthPerformanceListener
Optional. Receives structured timing samples for runtime readiness, wallet create/open RPCs, post-operation info adoption, and sync polling. Instrumentation stays off unless this is supplied: with it omitted no timing is measured and no samples are delivered. A listener that throws cannot break wallet work. Default: unset (disabled).

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.

wavelength-core.d.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.

wavelength-core.d.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;
}
clientWavelengthClient
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. On success it dispatches the info and best-effort calls refresh() (a locked or empty wallet can fail balance/list until bootstrap; that failure is swallowed); a failure moves phase to 'error' and rejects. Either way, a stop() the host issued while the start was in flight takes precedence: that stop governs the phase and the start leaves the snapshot to it (no info dispatch and no refresh on success, no error surfaced on failure), though the promise still resolves with the info or rejects as usual.
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 runs these automatically, keyed off phase, so hosts never reimplement them.

Activity-stream auto-refreshphase: 'ready'
Opens the transport's activity stream and, on each event, runs a bounded settle-reconcile: an immediate refresh() followed by up to three re-reads (at 750ms, 1500ms, and 3000ms) that stop early once the balance has moved off its pre-event baseline and held steady across two reads. This covers the daemon reporting an entry settled a beat before balance() reflects the new funds.
Activity-stream recoveryon activityStream
A terminal activityStream event triggers 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 snapshot becomes consistent again after a disconnect. The transports do not expose structured gap cursor or reason details.
Sync auto-pollphase: 'syncing'
Calls refresh() every 2000ms until the phase leaves 'syncing'. After 5 consecutive failures it stops polling and escalates to phase 'error' rather than polling forever.
Restore readiness pollphase: 'restoring'
Runs while any restoreWallet() is in flight, polling getInfo() every 1500ms until the wallet reports ready, then settles the restoreWallet() promise and kicks a refresh. When the request sets recoverState: true, the recovery scan is tracked separately through snapshot.recovery.
Background-refresh failure budgetall of the above
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 transitionon runtimeStopped
A runtimeStopped client event, whether from a clean stop() or a worker crash surfaced by the transport, moves phase to 'stopped' (unless the engine is already in 'error', which is preserved so a failure that caused the stop still surfaces) and wipes info, balance, and activity to null, null, and [] regardless, even if the host never called stop() itself.

WalletSnapshot

type

The engine’s immutable state snapshot, returned by getSnapshot() and delivered to subscribe() 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.

wavelength-core.d.ts
type WalletSnapshot = {
phase: RuntimePhase;
error: Error | null;
info: WalletInfo | null;
balance: Balance | null;
activity: Entry[];
recovery: RecoveryState;
logs: WavelengthLogPayload[];
};
phaseRuntimePhase
The current runtime/wallet lifecycle phase.
errorError | null
The last fatal runtime-level error, or null.
infoWalletInfo | null
The most recent complete wallet info, or null before the runtime reports it.
balanceBalance | null
The most recent wallet balance, or null before it is known.
activityEntry[]
The most recent activity entries, newest-first as returned by the daemon.
recoveryRecoveryState
The background recovery status set by restoreWallet(); see RecoveryState below.
logsWavelengthLogPayload[]
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.

wavelength-core.d.ts
type RecoveryState =
| { status: 'idle' }
| { status: 'restoring' }
| { status: 'done'; result: CreateWalletResult }
| { status: 'failed'; error: Error; walletUsable: boolean };
{ 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(): everything CreateWalletRequest accepts, with mnemonic promoted from optional to required, since a restore is meaningless without one.

wavelength-core.d.ts
type RestoreWalletRequest = CreateWalletRequest & {
mnemonic: string[];
};
mnemonicstring[]
The recovery phrase to restore from. Required (unlike CreateWalletRequest.mnemonic, which is optional).
passwordstring
The plain password the client base64-encodes into the daemon's byte field.
seedPassphrasestring
Optional. A BIP-39 passphrase applied on top of the mnemonic.
recoverStateboolean
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.
recoveryWindownumber
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.

wavelength-core.d.ts
createWallet(req: CreateWalletRequest): Promise<CreateWalletResult>
reqCreateWalletRequest
Parameters for creating (or importing) the wallet.
ReturnsPromise<CreateWalletResult>

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

CreateWalletRequest

wavelength-core.d.ts
type CreateWalletRequest = {
password: string;
mnemonic?: string[];
seedPassphrase?: string;
recoverState?: boolean;
recoveryWindow?: number;
};
passwordstring
The plain password the client base64-encodes into the daemon's byte field.
mnemonicstring[]
Optional. An existing mnemonic to restore from; a fresh one is generated when omitted.
seedPassphrasestring
Optional. A BIP-39 passphrase applied on top of the mnemonic.
recoverStateboolean
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.
recoveryWindownumber
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

wavelength-core.d.ts
type CreateWalletResult = {
mnemonic: string[];
encipheredSeed: string;
identityPubKey: string;
recoveryRan: boolean;
recoveredBoardingAddresses: number;
recoveredBoardingUTXOs: number;
recoveredVTXOs: number;
recoveredOORReceiveScripts: number;
recoveredOORRecipientEvents: number;
};
mnemonicstring[]
The seed words. Display this to the user for backup; it is not recoverable from the daemon afterward.
encipheredSeedstring
The password-enciphered seed, as stored by the daemon.
identityPubKeystring
The wallet's identity public key.
recoveryRanboolean
True when mnemonic was supplied and the daemon ran chain recovery to rediscover funds.
recoveredBoardingAddressesnumber
Count of boarding addresses recovered. Only meaningful when recoveryRan is true.
recoveredBoardingUTXOsnumber
Count of boarding UTXOs recovered.
recoveredVTXOsnumber
Count of VTXOs recovered.
recoveredOORReceiveScriptsnumber
Count of out-of-round receive scripts recovered.
recoveredOORRecipientEventsnumber
Count of out-of-round recipient events recovered.

unlockWallet

function

Unlocks an existing wallet with the given password.

wavelength-core.d.ts
unlockWallet(req: UnlockWalletRequest): Promise<UnlockWalletResult>
reqUnlockWalletRequest
The password to unlock with.
ReturnsPromise<UnlockWalletResult>

The daemon identity after unlock.

UnlockWalletRequest

wavelength-core.d.ts
type UnlockWalletRequest = {
password: string;
};
passwordstring
The plain password the client base64-encodes into the daemon's byte field.

UnlockWalletResult

wavelength-core.d.ts
type UnlockWalletResult = {
identityPubKey: string;
};
identityPubKeystring
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 ceremony, creating one on first use per device or unlocking the existing one thereafter.

wavelength-core.d.ts
openWalletFromPasskey(
req: OpenWalletFromPasskeyRequest,
): Promise<OpenWalletFromPasskeyResult>
reqOpenWalletFromPasskeyRequest
The passkey PRF output to derive the wallet from.
ReturnsPromise<OpenWalletFromPasskeyResult>

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

OpenWalletFromPasskeyRequest

wavelength-core.d.ts
type OpenWalletFromPasskeyRequest = {
prfOutput: string;
};
prfOutputstring
The PRF output (hex) derived from the passkey ceremony. See PasskeyAssertion.

OpenWalletFromPasskeyResult

wavelength-core.d.ts
type OpenWalletFromPasskeyResult = {
imported: boolean;
mnemonic: string[];
identityPubKey: string;
};
importedboolean
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.
mnemonicstring[]
The seed words. Populated only when imported is true, for backup display.
identityPubKeystring
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:

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() for portable low-level integrations.

getInfo

function

Returns the current normalized wallet info.

wavelength-core.d.ts
getInfo(): Promise<WalletInfo>
ReturnsPromise<WalletInfo>

The current wallet and daemon info.

status

function

Returns the daemon’s runtime status snapshot.

wavelength-core.d.ts
status(): Promise<WalletStatus>
ReturnsPromise<WalletStatus>

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

balance

function

Returns the current wallet balance.

wavelength-core.d.ts
balance(): Promise<Balance>
ReturnsPromise<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() when you need walletReady.

wavelength-core.d.ts
isRunning(): Promise<boolean>
ReturnsPromise<boolean>

true while the embedded daemon process is running.

WalletInfo

type

Wallet and daemon info returned by getInfo() and start().

wavelength-core.d.ts
type WalletInfo = {
version: string;
commit: string;
network: string;
blockHeight: number;
serverConnected: boolean;
walletType: string;
identityPubKey: string;
walletState: WalletState;
walletReady: boolean;
serverInfo?: ServerInfo;
};
versionstring
The daemon version string.
commitstring
The daemon build commit hash.
networkstring
The Bitcoin network the daemon is running against.
blockHeightnumber
The current chain tip height the wallet has synced to.
serverConnectedboolean
Whether the daemon's connection to the Ark server is currently up.
walletTypestring
The backing wallet implementation in use.
identityPubKeystring
The wallet's identity public key.
walletStateWalletState
The wallet lifecycle state, normalized to the SDK string union.
walletReadyboolean
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.
serverInfoServerInfo
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. The daemon learns these from its cached operator terms at bootstrap and on later terms refreshes.

wavelength-core.d.ts
type ServerInfo = {
freeRefreshWindowBlocks: number;
};
freeRefreshWindowBlocksnumber
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().

wavelength-core.d.ts
type WalletStatus = {
ready: boolean;
unlocked: boolean;
network: string;
balance: Balance;
pendingCount: number;
};
readyboolean
Whether the wallet is unlocked and fully usable.
unlockedboolean
Whether the wallet is currently unlocked (may still be syncing).
networkstring
The Bitcoin network the daemon is running against.
balanceBalance
The current wallet balance; see Balance below.
pendingCountnumber
The number of activity entries currently pending.

Balance

type

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

wavelength-core.d.ts
type Balance = {
confirmedSat: number;
pendingInSat: number;
pendingOutSat: number;
};
confirmedSatnumber
Spendable VTXO balance.
pendingInSatnumber
Inbound amount not yet confirmed.
pendingOutSatnumber
Outbound amount in flight.

Deposits and receiving

deposit

function

Generates an on-chain deposit (boarding) address.

wavelength-core.d.ts
deposit(req?: DepositRequest): Promise<DepositResult>
reqDepositRequest
Optional. Defaults to {} when omitted.
ReturnsPromise<DepositResult>

The boarding address and its initial Entry in the activity feed.

DepositRequest

wavelength-core.d.ts
type DepositRequest = {
amountSatHint?: number;
};
amountSatHintnumber
Optional. A hint for the amount (in sats) the caller intends to deposit.

DepositResult

wavelength-core.d.ts
type DepositResult = {
address: string;
entry: Entry;
};
addressstring
The boarding (on-chain) address to deposit to.
entryEntry
The activity entry tracking this deposit; see Entry.

receive

function

Generates a receive invoice for the requested amount.

wavelength-core.d.ts
receive(req: ReceiveRequest): Promise<ReceiveResult>
reqReceiveRequest
The amount (and optional memo) to request.
ReturnsPromise<ReceiveResult>

The invoice and its initial Entry in the activity feed.

ReceiveRequest

wavelength-core.d.ts
type ReceiveRequest = {
amountSat: number;
memo?: string;
};
amountSatnumber
The amount to request, in sats.
memostring
Optional. A memo attached to the invoice.

ReceiveResult

wavelength-core.d.ts
type ReceiveResult = {
invoice: string;
entry: Entry;
};
invoicestring
The BOLT-11 Lightning invoice to be paid.
entryEntry
The activity entry tracking this receive; see Entry.

Sending payments

Sending a payment follows a quote → confirm → pay flow. prepareSend() validates the request and returns a quote (the expected fee, rail, and a single-use sendIntentId) without moving funds; sendPrepared() then dispatches that exact quote. 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() for a quote → confirm → pay flow.

wavelength-core.d.ts
prepareSend(req: SendRequest): Promise<PrepareSendResult>
reqSendRequest
The Lightning invoice or on-chain address to quote a send for.
ReturnsPromise<PrepareSendResult>

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

sendPrepared

function

Dispatches a payment previously quoted by prepareSend().

wavelength-core.d.ts
sendPrepared(prepared: PrepareSendResult): Promise<SendResult>
preparedPrepareSendResult
The quote returned by prepareSend(). Its sendIntentId is consumed on dispatch; if dispatch fails, prepare a fresh send before retrying.
ReturnsPromise<SendResult>

The dispatched send’s activity entry and actual amounts.

send

function

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

wavelength-core.d.ts
send(req: SendRequest): Promise<SendResult>
reqSendRequest
The Lightning invoice or on-chain address to pay.
ReturnsPromise<SendResult>

The dispatched send’s activity entry and actual amounts.

SendRequest

type

Parameters accepted by prepareSend() and 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.

wavelength-core.d.ts
type SendRequest =
| {
invoice: string;
amountSat?: number;
note?: string;
maxFeeSat?: number;
}
| {
onchainAddress: string;
amountSat?: number;
sweepAll?: boolean;
note?: string;
maxFeeSat?: number;
};

Lightning arm

invoicestring
A Lightning invoice to pay.
amountSatnumber
Optional. The amount to send, in sats. Ignored on the invoice path: v1 requires an amount-bearing BOLT-11 invoice.
notestring
Optional. A note recorded with the activity.
maxFeeSatnumber
Optional. A cap on the fee, in sats.

On-chain arm

onchainAddressstring
An on-chain address to pay.
amountSatnumber
Optional. The amount to send, in sats. Provide this or set sweepAll.
sweepAllboolean
Optional. When true, sweeps the entire spendable balance to the destination.
notestring
Optional. A note recorded with the activity.
maxFeeSatnumber
Optional. A cap on the fee, in sats.

PrepareSendResult

type

The quote and intent id returned by prepareSend().

wavelength-core.d.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;
};
sendIntentIdstring
Single-use id identifying this quote; pass the whole result object to sendPrepared() to dispatch it.
amountSatnumber
The amount that will be sent, in sats.
expectedFeeSatnumber
The expected fee, in sats.
feeKnownboolean
Whether expectedFeeSat is a firm quote rather than an estimate.
expectedTotalOutflowSatnumber
The expected total amount leaving the wallet (amount plus fee), in sats.
totalOutflowKnownboolean
Whether expectedTotalOutflowSat is firm rather than an estimate.
railSendRail
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.
destinationSummarystring
A human-readable summary of the destination.
invoiceDescriptionstring
The invoice's embedded description, for Lightning sends.
paymentHashstring
The Lightning payment hash, when applicable.
expiresAtUnixnumber
Unix timestamp after which this quote (and its sendIntentId) is no longer valid.
selectedOutpointsstring[]
The VTXO outpoints selected to fund this send; sendPrepared() spends exactly this set.
warningstring
An optional human-readable warning about this quote (e.g. a high fee).

SendResult

type

The result of a dispatched send, returned by sendPrepared() and send().

wavelength-core.d.ts
type SendResult = {
entry: Entry;
actualAmountSat: number;
paymentHash?: string;
};
entryEntry
The activity entry tracking this send; see Entry.
actualAmountSatnumber
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.
paymentHashstring
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.

wavelength-core.d.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.

wavelength-core.d.ts
function classifyDestination(raw: string): Destination

Destination

type

The result of classifyDestination().

wavelength-core.d.ts
type Destination =
| { kind: 'empty' }
| { kind: 'invoice'; amount: InvoiceAmount }
| { kind: 'address' };
{ 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.

wavelength-core.d.ts
type InvoiceAmount =
| { status: 'known'; sat: number }
| { status: 'amountless' }
| { status: 'unrepresentable' };
{ 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.

wavelength-core.d.ts
list(req?: ListRequest): Promise<ListResult>
reqListRequest
Optional. Defaults to {} (the activity view) when omitted.
ReturnsPromise<ListResult>

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

Filter the activity view by one or more entry kinds:

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

ListRequest

wavelength-core.d.ts
type ListRequest = {
view?: ListView;
pendingOnly?: boolean;
kinds?: EntryKind[];
limit?: number;
offset?: number;
cursor?: string;
};
viewListView
Optional. Which view to list: activity entries, VTXOs, or on-chain outputs. Default: 'activity'.
pendingOnlyboolean
Optional. When true, returns only pending items. Applies to the activity view only.
kindsEntryKind[]
Optional. Returns only the selected entry kinds. Applies to the activity view only.
limitnumber
Optional. The maximum number of items to return; zero uses the daemon default.
offsetnumber
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.
cursorstring
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.

wavelength-core.d.ts
type ListResult = {
view: ListView;
activity?: ActivityList;
vtxos?: VTXOInventory;
onchain?: OnchainHistory;
};
viewListView
The populated variant. Mirrors the request’s view; an empty request view is reported as 'activity'.
activityActivityList
Populated when view === 'activity'.
vtxosVTXOInventory
Populated when view === 'vtxos'. See the balances-and-vtxos guide for the VTXO shape.
onchainOnchainHistory
Populated when view === 'onchain'.

ListView

wavelength-core.d.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

wavelength-core.d.ts
type ActivityList = {
entries: Entry[];
total: number;
hasMore: boolean;
nextCursor: string;
};
entriesEntry[]
The matching activity entries; see Entry.
totalnumber
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.
hasMoreboolean
Whether more entries exist after this page.
nextCursorstring
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.

wavelength-core.d.ts
type VTXOInventory = {
vtxos: WalletVTXO[];
total: number;
};
vtxosWalletVTXO[]
The VTXOs on the current page.
totalnumber
The total number of matching VTXOs.

WalletVTXO

type

One spendable or spent VTXO in a wallet inventory.

wavelength-core.d.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.

wavelength-core.d.ts
type OnchainHistory = {
txs: OnchainTx[];
total: number;
hasMore: boolean;
};
txsOnchainTx[]
The on-chain transactions on the current page.
totalnumber
The total number of matching transactions.
hasMoreboolean
Whether another page is available.

OnchainTx

type

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

wavelength-core.d.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.

wavelength-core.d.ts
subscribe(listener: WavelengthListener): () => void
listenerWavelengthListener
Callback invoked with each WavelengthEvent.
Returns() => void

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

WavelengthListener

wavelength-core.d.ts
type WavelengthListener = (event: WavelengthEvent) => void;

See 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() is called.

wavelength-core.d.ts
startActivity(opts?: ActivityStreamOptions): Promise<void>
// 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,
});
opts.includeExistingboolean
Optional. When true, immediately emits an activity event for every entry that already exists, in addition to future changes.
opts.kindsEntryKind[]
Optional. Streams only the selected activity kinds.
opts.cursornumber
Optional. Resumes after the last monotonic Entry.cursor the consumer processed. Must be a nonnegative safe integer.

ActivityStreamOptions

wavelength-core.d.ts
type ActivityStreamOptions = {
includeExisting?: boolean;
kinds?: EntryKind[];
cursor?: number;
};
ReturnsPromise<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 adds reconciliation and bounded cursor-based recovery for apps that want that managed behavior.

stopActivity

function

Closes the activity stream opened by startActivity().

wavelength-core.d.ts
stopActivity(): void
Returnsvoid

Nothing; stops emitting 'activity' events synchronously.

Entry

type

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

wavelength-core.d.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;
};
idstring
The activity id. Not a payment hash; see SendResult.paymentHash for that.
kindEntryKind
The user-visible activity category.
statusEntryStatus
The collapsed pending/complete/failed state. See the Phase vs Status note below.
amountSatnumber
The activity amount, in sats.
feeSatnumber
The fee associated with this activity, in sats.
counterpartystring
A human-readable counterparty label, when known.
createdAtstring
When the entry was created.
updatedAtstring
When the entry was last updated.
notestring
An optional note recorded with the activity.
failureReasonstring
Human-readable supplement to failureCode; populated only when status is 'failed'.
failureCodeEntryFailureCode
Stable, machine-readable classification of why the entry failed. Empty unless status is 'failed'.
cursornumber
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.
progressEntryProgress
Optional. Lifecycle metadata the daemon normalized for this entry. Absent when the backing subsystem supplied no progress hint.
requestEntryRequest
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. Fields are populated on a best-effort basis by the backing subsystem; an empty field means not applicable or not yet known.

wavelength-core.d.ts
type EntryProgress = {
phase: EntryPhase;
phaseLabel: string;
paymentHash: string;
txid: string;
confirmationHeight: number;
vTXOOutpoint: string;
preimage: string;
};
phaseEntryPhase
The coarse lifecycle phase for the entry.
phaseLabelstring
The short lowercase label the daemon emitted; render this directly instead of switching on phase if you prefer.
paymentHashstring
Populated for Lightning-backed send/receive entries.
txidstring
Populated when the backing ledger row has an on-chain txid.
confirmationHeightnumber
Populated once the source records it.
vTXOOutpointstring
Populated when a swap observes the Ark vHTLC output.
preimagestring
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. Exactly one variant’s fields are populated, named by type; read type first and treat the other fields as zero.

wavelength-core.d.ts
type EntryRequest = {
type: EntryRequestType;
lightningInvoice: string;
paymentHash: string;
onchainAddress: string;
arkAddress: string;
};
typeEntryRequestType
Names the populated variant.
lightningInvoicestring
The BOLT-11 payment request. Populated when type is 'lightning'.
paymentHashstring
Identifies the Lightning invoice and stays stable after the invoice is no longer convenient to display. Populated when type is 'lightning'.
onchainAddressstring
The bech32 on-chain address originally issued or targeted. Populated when type is 'onchain'.
arkAddressstring
The Ark address originally issued or targeted. Populated when type is 'ark'.

EntryKind

type

The user-visible wallet activity category.

wavelength-core.d.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.

wavelength-core.d.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.

wavelength-core.d.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.

EntryFailureCode

type

A wrapper-owned, stable classification of why a failed Entry failed.

wavelength-core.d.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 carries.

wavelength-core.d.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

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.

wavelength-core.d.ts
exit(req: ExitRequest): Promise<ExitResult>
reqExitRequest
The outpoint and either an optional cooperative destination or the exact unilateral acknowledgement.
ReturnsPromise<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:

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:

await client.exit({
outpoint,
forceUnrollAck: FORCE_UNROLL_ACK,
});
wavelength-core.d.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;
outpointstring
The VTXO outpoint to exit, in "txid:index" format.
destinationstring
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.
forceUnrollAcktypeof 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.

wavelength-core.d.ts
type ExitResult = {
path: ExitPath;
cooperative: boolean;
queuedOutpoints: string[];
created: boolean;
actorID: string;
cooperativeError: string;
};
pathExitPath
Discriminates between the three legal outcomes; switch on this before reading the variant fields below.
cooperativeboolean
true iff path === 'cooperative'. Retained for backwards compatibility; prefer path.
queuedOutpointsstring[]
The outpoints the cooperative leave admitted into a round. Populated only when path === 'cooperative'.
createdboolean
Whether the unilateral-unroll path spawned a fresh job. Populated when path is 'unilateral' or 'unilateral_fallback'.
actorIDstring
Identifies the durable unroll job that owns the unilateral path. Populated when path is 'unilateral' or 'unilateral_fallback'.
cooperativeErrorstring
Retained for source compatibility with a prior SDK fallback shape; current daemon behavior returns cooperative failures directly rather than populating this.

ExitPath

wavelength-core.d.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.

wavelength-core.d.ts
exitStatus(req: ExitStatusRequest): Promise<ExitStatusResult>
reqExitStatusRequest
The outpoint whose exit status is queried.
ReturnsPromise<ExitStatusResult>

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

ExitStatusRequest

wavelength-core.d.ts
type ExitStatusRequest = {
outpoint: string;
detailed?: boolean;
};
outpointstring
The VTXO outpoint whose exit status is queried.
detailedboolean
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.

wavelength-core.d.ts
type ExitStatusResult = {
found: boolean;
status: ExitJobStatus;
sweepTxid: string;
lastError: string;
phaseDetail: string;
progress?: ExitProgress;
cSV?: ExitCSV;
fees?: ExitFees;
bestCaseBlocksRemaining: number;
currentHeight: number;
};
foundboolean
Whether an exit job exists for the requested outpoint.
statusExitJobStatus
The job’s current status. Meaningful only when found is true.
sweepTxidstring
The sweep transaction id, once known.
lastErrorstring
The last error the job recorded, if any.
phaseDetailstring
A one-line human description of the current phase. Empty on a coarse (non-detailed) query.
progressExitProgress
Recovery-tree materialization progress. Nil on a coarse query, or when no live actor backs the job.
cSVExitCSV
The target’s CSV maturity countdown. Nil until the target confirms.
feesExitFees
The on-chain cost breakdown for the exit. Nil on a coarse query.
bestCaseBlocksRemainingnumber
The optimistic block count until a confirmed sweep. Zero on a coarse query.
currentHeightnumber
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.

wavelength-core.d.ts
type ExitProgress = {
confirmedTxs: number;
inFlightTxs: number;
readyTxs: number;
blockedTxs: number;
totalTxs: number;
currentLayer: number;
totalLayers: number;
targetConfirmed: boolean;
allProofConfirmed: boolean;
};
confirmedTxsnumber
Proof transactions confirmed on-chain.
inFlightTxsnumber
Proof transactions broadcast but not yet observed confirmed.
readyTxsnumber
Proof transactions ready to broadcast now.
blockedTxsnumber
Proof transactions still waiting on an unconfirmed in-proof parent.
totalTxsnumber
Total transactions in the exit proof tree.
currentLayernumber
The frontier layer index: the shallowest topological layer (roots first) that still holds an unconfirmed transaction.
totalLayersnumber
The depth of the exit proof tree.
targetConfirmedboolean
True once the target VTXO transaction has confirmed.
allProofConfirmedboolean
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.

wavelength-core.d.ts
type ExitCSV = {
targetConfirmHeight: number;
maturityHeight: number;
blocksRemaining: number;
mature: boolean;
};
targetConfirmHeightnumber
The height at which the target transaction confirmed.
maturityHeightnumber
The height at which the CSV timelock matures.
blocksRemainingnumber
Blocks remaining until maturity.
matureboolean
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.

wavelength-core.d.ts
type ExitFees = {
cPFPFeeSat: number;
sweepFeeSat: number;
totalCostSat: number;
spentSoFarSat: number;
vTXOAmountSat: number;
netRecoveredSat: number;
feeRateSatVByte: number;
sweepFeeActual: boolean;
};
cPFPFeeSatnumber
The estimated total CPFP fee, in sats.
sweepFeeSatnumber
The sweep fee, in sats. Real rather than estimated when sweepFeeActual is true.
totalCostSatnumber
The projected on-chain cost of the whole exit, in sats.
spentSoFarSatnumber
The estimated fee committed so far, in sats.
vTXOAmountSatnumber
The VTXO value being recovered, in sats.
netRecoveredSatnumber
The estimated net recoverable after fees, in sats.
feeRateSatVBytenumber
The fee rate used, in sat/vByte.
sweepFeeActualboolean
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.

wavelength-core.d.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.

wavelength-core.d.ts
exitSummary(req?: ExitSummaryRequest): Promise<ExitSummaryResult>
reqExitSummaryRequest
Takes no arguments; the daemon reports the wallet-wide portfolio.
ReturnsPromise<ExitSummaryResult>

The in-progress exits plus aggregate totals.

ExitSummaryRequest

Takes no arguments.

wavelength-core.d.ts
type ExitSummaryRequest = Record<string, never>;

ExitSummaryResult

wavelength-core.d.ts
type ExitSummaryResult = {
exits: ExitSummaryEntry[];
totalExits: number;
totalVTXOAmountSat: number;
totalEstFeeSat: number;
totalEstNetRecoveredSat: number;
};
exitsExitSummaryEntry[]
One entry per in-progress exit.
totalExitsnumber
The number of in-progress exits.
totalVTXOAmountSatnumber
The combined VTXO value being recovered, in sats.
totalEstFeeSatnumber
The combined estimated on-chain fees, in sats.
totalEstNetRecoveredSatnumber
The combined estimated net recoverable after fees, in sats.

ExitSummaryEntry

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

wavelength-core.d.ts
type ExitSummaryEntry = {
outpoint: string;
status: ExitJobStatus;
vTXOAmountSat: number;
estTotalFeeSat: number;
estNetRecoveredSat: number;
};
outpointstring
The VTXO outpoint being exited.
statusExitJobStatus
The exit job’s current status.
vTXOAmountSatnumber
The VTXO value being recovered, in sats.
estTotalFeeSatnumber
The estimated total on-chain fee for this exit, in sats.
estNetRecoveredSatnumber
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.

wavelength-core.d.ts
getExitPlan(req: GetExitPlanRequest): Promise<GetExitPlanResult>
reqGetExitPlanRequest
The outpoints to plan an exit for.
ReturnsPromise<GetExitPlanResult>

Per-outpoint funding plans plus aggregate totals.

GetExitPlanRequest

wavelength-core.d.ts
type GetExitPlanRequest = {
outpoints: string[];
confTarget?: number;
};
outpointsstring[]
The VTXO outpoints to plan an exit for.
confTargetnumber
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.

wavelength-core.d.ts
type GetExitPlanResult = {
plans: ExitPlanEntry[];
feeRateSatPerVByte: number;
canStart: boolean;
totalFundingShortfallSat: number;
totalRecommendedFundingSat: number;
};
plansExitPlanEntry[]
One entry per requested outpoint.
feeRateSatPerVBytenumber
The fee rate used to compute the plan.
canStartboolean
Whether every outpoint in the plan is ready to exit right now.
totalFundingShortfallSatnumber
The combined backing-wallet funding still needed across all outpoints.
totalRecommendedFundingSatnumber
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.

wavelength-core.d.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;
};
outpointstring
The VTXO outpoint this entry describes.
fundingAddressstring
The backing-wallet address to fund for this exit.
requiredConfirmationsnumber
Confirmations the funding UTXO(s) need before the exit can start.
requiredFeeUTXOCountnumber
The number of fee UTXOs required.
usableFeeUTXOCountnumber
The number of fee UTXOs currently usable.
recommendedUTXOAmountSatnumber
The recommended amount per funding UTXO, in sats.
recommendedTotalFundingSatnumber
The recommended total funding amount, in sats.
fundingShortfallSatnumber
The funding still needed before this outpoint can exit, in sats.
canStartboolean
Whether this outpoint is ready to exit right now.
infeasibilityReasonExitInfeasibilityReason
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.
exitJobFoundboolean
Whether an exit job already exists for this outpoint.
exitStatusExitJobStatus
The existing job’s status, when exitJobFound is true.
sweepTxidstring
The sweep transaction id, once known.
lastErrorstring
The last error the existing job recorded, if any.
errstring
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.

wavelength-core.d.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

function

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

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

On the unilateral path it previews funding with 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.

optsExitBatchOptions
The batch mode and outpoints, plus client (the WavelengthClient to drive), an optional AbortSignal, and an optional onEvent progress callback.
ReturnsPromise<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.

wavelength-core.d.ts
type ExitBatchOptions =
| { mode: 'cooperative'; outpoints: string[]; destination?: string }
| { mode: 'unilateral'; outpoints: string[]; confTarget?: number };
{ 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.

wavelength-core.d.ts
type ExitBatchEvent =
| { type: 'planned'; plan: GetExitPlanResult }
| { type: 'starting'; outpoint: string }
| { type: 'started'; outpoint: string; result: ExitResult }
| { type: 'stopped'; stoppedBy: ExitBatchStop; remaining: string[] };
{ 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.

wavelength-core.d.ts
type ExitBatchStop =
| { reason: 'infeasible'; plan: GetExitPlanResult }
| { reason: 'rejected'; outpoint: string; error: Error };
{ 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().

wavelength-core.d.ts
type ExitBatchResult = {
started: { outpoint: string; result: ExitResult }[];
skipped: string[];
remaining: string[];
stoppedBy?: ExitBatchStop;
};
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.
skippedstring[]
Outpoints that already had a running exit job and were left alone rather than double-started.
remainingstring[]
Outpoints never started, because the batch stopped early.
stoppedByExitBatchStop
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.

wavelength-core.d.ts
function isExitInfeasibilityFundable(
reason: ExitInfeasibilityReason,
): boolean
reasonExitInfeasibilityReason
The infeasibility reason from an ExitPlanEntry, typically read from a getExitPlan() response.
Returnsboolean

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.

wavelength-core.d.ts
sweepWallet(req: SweepWalletRequest): Promise<SweepWalletResult>
reqSweepWalletRequest
The destination and broadcast flag for the sweep.
ReturnsPromise<SweepWalletResult>

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

SweepWalletRequest

wavelength-core.d.ts
type SweepWalletRequest = {
destinationAddress: string;
broadcast?: boolean;
feeRateSatPerVByte?: number;
confTarget?: number;
};
destinationAddressstring
The on-chain address to sweep the backing wallet to.
broadcastboolean
Optional. When true, broadcasts the sweep; when false (the default), only previews it.
feeRateSatPerVBytenumber
Optional. An explicit fee rate, in sat/vByte.
confTargetnumber
Optional. A confirmation target (in blocks) used to estimate fees.

SweepWalletResult

wavelength-core.d.ts
type SweepWalletResult = {
inputs: WalletSweepInput[];
totalInputSat: number;
estimatedFeeSat: number;
netAmountSat: number;
feeRateSatPerVByte: number;
canBroadcast: boolean;
txid: string;
failureReason: string;
};
inputsWalletSweepInput[]
The backing-wallet UTXOs selected for this sweep.
totalInputSatnumber
The combined amount of the selected inputs, in sats.
estimatedFeeSatnumber
The estimated fee, in sats.
netAmountSatnumber
The amount that will reach destinationAddress after fees, in sats.
feeRateSatPerVBytenumber
The fee rate used, in sat/vByte.
canBroadcastboolean
Whether the sweep is currently valid to broadcast.
txidstring
The broadcast transaction id. Populated only when broadcast was true and the sweep succeeded.
failureReasonstring
A human-readable reason the sweep cannot broadcast, when canBroadcast is false.

WalletSweepInput

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

wavelength-core.d.ts
type WalletSweepInput = {
outpoint: string;
amountSat: number;
};
outpointstring
The UTXO outpoint.
amountSatnumber
The UTXO amount, in sats.

See the leaving Ark guide 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.

wavelength-core.d.ts
callFacade<T = unknown>(
method: FacadeMethod,
params?: unknown,
): Promise<T>
methodFacadeMethod
One of the portable facade method names listed below.
paramsunknown
Optional. The raw mobile/wasm request shape for that method, not the typed SDK request mapper.
ReturnsPromise<T>

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

FacadeMethod

wavelength-core.d.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. The lifecycle verbs start and stop are rejected too: call the typed start() / stop() methods, which own the runtime lifecycle (and, on the web transports, the cross-tab runtime lock). 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.

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.

wavelength-core.d.ts
function camelizeKeys<T = unknown>(value: unknown): T
valueunknown
The raw daemon response (or any nested value) to camelize.
ReturnsT

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().

wavelength-core.d.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(). restoring is owned by the 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.

wavelength-core.d.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(). Runtime-owned phases such as starting and stopped are represented by RuntimePhase, not this type.

wavelength-core.d.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.

wavelength-core.d.ts
function phaseFromInfo(info: {
walletState?: WalletState;
walletReady?: boolean;
}): WalletPhase
info.walletStateWalletState
Optional. The wallet lifecycle state to derive a phase from.
info.walletReadyboolean
Optional. When true, short-circuits directly to 'ready' regardless of walletState.
ReturnsWalletPhase

'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() 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.

wavelength-core.d.ts
function normalizeInfo(raw: unknown): WalletInfo
rawunknown
The raw daemon Info payload (untrusted shape).
ReturnsWalletInfo

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.

wavelength-core.d.ts
function walletStateFromProto(
value: number | WalletState | undefined,
): WalletState
valuenumber | WalletState | undefined
The raw walletState as a proto number, an SDK string, or undefined.
ReturnsWalletState

'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, '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.

wavelength-core.d.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.

wavelength-core.d.ts
type ActivityStreamState = 'ended' | 'failed';

ActivityStreamPayload

type

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

wavelength-core.d.ts
type ActivityStreamPayload =
| { state: 'ended' }
| { state: 'failed'; message: string };

WavelengthEventType

type

The set of WavelengthEvent discriminants.

wavelength-core.d.ts
type WavelengthEventType = WavelengthEvent['type'];

WavelengthListener

type

A subscriber callback invoked with each WavelengthEvent, passed to subscribe().

wavelength-core.d.ts
type WavelengthListener = (event: WavelengthEvent) => void;

WavelengthLogPayload

type

The payload carried by a 'log' event.

wavelength-core.d.ts
type WavelengthLogPayload = {
level: WavelengthLogLevel;
message: string;
};
levelWavelengthLogLevel
The severity of the log line.
messagestring
The human-readable log message.

WavelengthLogLevel

type

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

wavelength-core.d.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.

WavelengthPerformanceEvent

type

A structured timing sample. These are opt-in diagnostics: without an onPerformance listener no timing is measured and no sample is delivered, so leaving it off costs little more than a check per measured boundary.

wavelength-core.d.ts
type WavelengthPerformanceEvent = {
stage: 'runtime' | 'wallet' | 'passkey';
phase: string;
durationMs: number;
detail?: Record<string, string | number | boolean>;
};
stage'runtime' | 'wallet' | 'passkey'
The broad subsystem being measured: runtime readiness and wasm loading, wallet RPCs and engine bookkeeping, or a passkey ceremony.
phasestring
The measured boundary within the stage, for example wasmTotal, clientReady, createTotal, unlockTotal, adoptInfo or sync. Deliberately a string, so a transport can report boundaries this package does not know about.
durationMsnumber
Elapsed wall-clock milliseconds for the boundary.
detailRecord<string, string | number | boolean>
Optional low-cardinality context for interpreting the sample, such as the load path taken, the outcome, or a retry count. Never carries addresses, amounts or passkey output.

WavelengthPerformanceListener

type

Receives performance samples. Pass one as onPerformance to a client factory, createWalletEngine, or createWebPasskeyCeremony. Delivery is isolated from wallet behavior: a listener that throws is swallowed rather than failing the operation being measured.

wavelength-core.d.ts
type WavelengthPerformanceListener = (
event: WavelengthPerformanceEvent,
) => void;

Errors

WavelengthError

class

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

wavelength-core.d.ts
class WavelengthError extends Error {
readonly code: WavelengthErrorCode;
constructor(
message: string,
code?: WavelengthErrorCode,
options?: { cause?: unknown },
);
}
messagestring
Human-readable description of what went wrong.
codeWavelengthErrorCode
Machine-readable error code. Defaults to wavelength_error.
options.causeunknown
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; most daemon-originated errors fall back to wavelength_error, except recognized storage-contention messages on start(), which the web transports map to wallet_locked. The (string & {}) arm keeps the union open for forward compatibility while still offering autocomplete on the known codes.

wavelength-core.d.ts
type WavelengthErrorCode =
| 'wavelength_error'
| 'runtime_not_ready'
| 'asset_load_failed'
| 'asset_integrity_failed'
| 'worker_error'
| 'wallet_locked'
| 'runtime_lock_unavailable'
| 'unsupported_facade_method'
| 'invalid_cursor'
| 'invalid_config'
| (string & {});
Code Thrown when
wavelength_error The generic default: any SDK error without a more specific code, and daemon-originated failures today, except recognized storage-contention messages on start() that map to wallet_locked.
runtime_not_ready The wasm runtime is not callable: it exited before signaling ready, or its call entry point is missing once loading has finished.
asset_load_failed ready() fails to load the runtime assets (wasm binary or its supporting files).
asset_integrity_failed A runtime asset was downloaded in full and recognized as a runtime asset, but its bytes did not match the pinned digest. asset_load_failed covers most other ways a runtime asset failed to reach a usable state, including a body that does not look like a runtime asset at all, or, on the main thread, an already-verified script blocked from executing. In the default worker transport that block reaches the client as an unrecognized browser message and surfaces as wavelength_error, as does a downloaded, verified module that fails to compile, which is not an asset problem.
worker_error The worker transport’s underlying Worker fails or crashes.
wallet_locked The wallet is already running in another tab or window of the same origin. The daemon’s browser storage is exclusive to one runtime, so start() fails immediately rather than corrupting or losing data. Unrelated to the locked phase, which means a wallet on this device is waiting to be unlocked.
runtime_lock_unavailable The browser refused or dropped the runtime lock request itself (for example while the document is shutting down). Unlike wallet_locked, this says nothing about another tab holding the wallet.
unsupported_facade_method A call names a method the daemon facade does not expose.
invalid_cursor startActivity() is given a cursor that is not a nonnegative safe integer.
invalid_config RuntimeConfig validation fails before the daemon starts.

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.

wavelength-core.d.ts
class PasskeyCancelledError extends Error {
constructor(message?: string);
}
messagestring
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.

wavelength-core.d.ts
function toError(value: unknown): Error
valueunknown
The thrown value to normalize; may already be an Error.
ReturnsError

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.

wavelength-core.d.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.

wavelength-core.d.ts
type PasskeyAssertion = {
prfOutput: string;
credentialId: string;
};
prfOutputstring
The PRF output (hex) shared with the Go SDK. Pass this into OpenWalletFromPasskeyRequest.prfOutput.
credentialIdstring
The credential id that produced the PRF output.

PasskeyCeremony

type

The per-platform passkey ceremony contract a host injects to drive openWalletFromPasskey(). Injecting it keeps consumers of this contract free of any transport dependency: 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).

wavelength-core.d.ts
type PasskeyCeremony = {
supportsPasskeyPrf(): Promise<boolean>;
registerPasskeyWallet(appName: string): Promise<PasskeyAssertion>;
assertPasskeyPrf(allowCredentialId?: string): Promise<PasskeyAssertion>;
};
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.