WDK wallet adapter for the Liquid network. Wraps an in-process LWK (Liquid Wallet Kit) wallet in the WDK account model — no external daemon required.
It is the wallet foundation for KaleidoSwap's native Liquid DEX (L-BTC ↔ USDt-Liquid swaps).
npm install @kaleidorg/wdk-wallet-liquid @tetherto/wdk-wallet@tetherto/wdk-wallet is a peer dependency.
The package transparently selects the right LWK build via the package
imports map (#lwk):
| Environment | Binding | Notes |
|---|---|---|
| Node / Bare (default) | lwk_node |
wasm-bindgen --target nodejs; self-instantiates, no flags needed. |
Browser (browser) |
lwk_wasm |
wasm-bindgen --target bundler; optional peer dependency. |
React Native (react-native) |
lwk-rn |
Blockstream's UniFFI→JSI native module — runs on Hermes, no WASM. Optional peer. |
lwk_node ships as a regular dependency, so Node usage is zero-config.
For browser/bundler usage (e.g. a Chrome MV3 extension service worker),
install lwk_wasm explicitly and ensure your bundler can import WebAssembly
as an ES module:
npm install lwk_wasm- Vite: add
vite-plugin-wasmandvite-plugin-top-level-await. - webpack 5: enable
experiments.asyncWebAssembly.
For React Native (Hermes has no WebAssembly engine), install the native
binding and let Metro pick the react-native condition:
npm install lwk-rn # requires a config-plugin / pod + gradle native buildEnsure your Metro config resolves the react-native export condition
(resolver.unstable_conditionNames = ['react-native', 'require', 'import']).
The lwk-rn Signer lacks signMessage() / getMasterXpub(); LiquidAccount
feature-detects those (message signing throws on RN; keyPair falls back to the
key-origin fingerprint), so the core wallet works unchanged.
There is no async init step — the bundler instantiates the WASM during
module load, so the API is identical to the Node path. (The lwk_wasm bundle
is ~10 MB; mind cold-start in constrained contexts.)
Liquid keys live in-process. LWK provides a watch-only Confidential
Transaction (CT) descriptor wallet (Wollet) plus a software Signer
derived from a BIP-39 mnemonic. Esplora is the chain backend used for
scanning and broadcasting.
The SLIP-77 CT descriptor covers every address, so there is a single logical
account — getAccount(index) always returns the same LiquidAccount.
import LiquidWalletManager from '@kaleidorg/wdk-wallet-liquid'
const wallet = new LiquidWalletManager(mnemonic, { network: 'testnet' })
const account = await wallet.getAccount()
await account.getAddress() // next CT receive address
await account.getBalance() // L-BTC balance (satoshis, bigint)
await account.getTokenBalance(assetId) // any Liquid asset balance
await account.transfer({ recipient, amount, feeRate })
await account.sendAsset({ assetId, recipient, amount, feeRate })
await account.listAssets()
await account.listUnspents()
await account.listTransactions()
wallet.dispose()| Option | Default | Description |
|---|---|---|
network |
'testnet' |
'mainnet', 'testnet' or 'regtest'. |
esploraUrl |
network default | Esplora API base URL. |
mnemonic |
— | Required only when the seed is passed as bytes. |
npm testOffline operations (key derivation, address generation, message signing) are
exercised against the real lwk_node WASM; balance and transfer paths require
a funded testnet wallet and are verified manually.
Apache-2.0