Inside the wdk-rgb-lightning Architecture: A Developer Walkthrough

Diagram of the wdk-rgb-lightning module architecture, showing WalletManagerRGBLightning and WalletAccountRGBLightning sitting between RGB Lightning Node and Tether's WDK, with separate native bindings branching to Node.js and Bare

RGB Lightning support in Tether’s WDK is now live. This piece follows up by describing the technical part behind it: how Utexo packaged RGB Lightning as a WDK module, what the module exposes, and what its early-beta status actually means in practice.

In Brief

  • The wdk-rgb-lightning architecture wraps RGB Lightning Node (RLN) inside WDK’s module interface, through two entry points: WalletManagerRGBLightning and WalletAccountRGBLightning
  • Utexo packages the native layer twice: a Node-native package for server and desktop hosts, and a statically-linked Bare-native package for WDK’s mobile runtime
  • Beyond Lightning and RGB transfers, the module adds LSP support, Lightning Address and UMA-style addresses, and VSS backup
  • Signing runs through an in-process VLS (Validating Lightning Signer); keyPair.privateKey stays null by design
  • A pre-1.0 beta, maintained by Utexo with real engineering discipline: test coverage raised from roughly 14.6% to about 98%

Why Does RGB Lightning Need Its Own Native Layer Inside WDK?

WDK is built around modular wallet packages, so the WDK core carries no blockchain-specific logic of its own. In fact, each module provides its own wallet manager and wallet account implementation, then the app registers them with WDK. Bitcoin, EVM, and on-chain RGB support all follow the same pattern, so RGB Lightning had to fit the same shape.

The first challenge was native compatibility, since RGB Lightning runs on Utexo’s fork of RGB Lightning Node (RLN), a modified rust-lightning build that combines LDK for the Lightning protocol logic with rgb-lib for RGB, plus the node logic needed for channels, invoices, payments, transfers, and local wallet state. The stack runs on RGB Protocol on Bitcoin v0.11.1, which any developer can verify by following the dependency chain down from rgb-lib to the underlying protocol crates.

WDK mobile applications, however, run wallet logic inside a Bare worklet, a sandboxed JavaScript runtime hosted through React Native. Bare worklets cannot dynamically load shared libraries, and iOS App Store policy forbids dynamic linking regardless of runtime, so ordinary Node native bindings are not enough on mobile.

The fix wraps the Rust core in a C FFI, a Foreign Function Interface, the C-compatible layer that lets code written in one language call functions written in another. The cbindgen command generates that FFI directly from the Rust source. Node hosts then compile against it using napi-rs, which builds a dynamically linked .node addon (a native binary that Node.js can load and call just like an ordinary JavaScript module).

Bare worklets use the same FFI, but through cmake-bare, which links the core statically instead, producing a single .bare addon that works across iOS, Android, and macOS. Both bindings expose the same JavaScript surface, so the WDK module picks the correct one at load time and the wallet code above it never has to change between a server, a desktop app, and a mobile app.

How Is the Module Structured?

Once the native layer existed, Utexo built the WDK module itself as a package that adapts RGB Lightning Node into WDK’s wallet architecture, through two pieces.

WalletManagerRGBLightning is the module’s entry point, the part WDK registers directly. It receives the wallet seed and the RGB Lightning configuration, prepares the native node, and creates the wallet account.

WalletAccountRGBLightning is the account object that an app actually calls. It exposes the standard WDK operations that every module supports, like wallet information, balance checks, fee estimation, message signing, sending transactions, plus two sets of module-specific methods:

  • Lightning operations: connecting peers, opening and listing channels, creating and decoding invoices, sending payments, and checking payment history
  • RGB operations: creating RGB invoices, sending RGB assets, checking RGB balances, listing assets, refreshing transfers, and reading asset metadata

Together, the two objects allow an app to support both Lightning payments and RGB asset transfers over Lightning through a single WDK module.

What Else Does the Module Add?

Three additional pieces round out the account surface:

  • LSP support: the module can connect to a Lightning Service Provider, use LSP-assisted receive and send flows, and support asynchronous payments
  • Lightning Address and UMA-style addresses: the module supports Lightning Address, and for compatibility across the WDK ecosystem, also accepts UMA-style addresses through the same payment flow
  • VSS backup: the module can back up Lightning and RGB node state, while the WDK wallet seed itself stays inside WDK’s normal secret boundary

How Does Signing Work?

Signing runs through an in-process VLS (Validating Lightning Signer), which handles channel-state cryptography on the module’s behalf. By design, the module never holds the raw private key directly: the field meant to store it internally stays empty.

What Are the Native Dependencies and Supported Platforms?

The module ships as two separate native packages: @utexo/rgb-lightning-node-nodejs for Node.js 18+ hosts, and @utexo/rgb-lightning-node-bare for mobile and other Bare targets. Verified builds currently cover macOS, Linux, Android, and iOS, including simulators. Windows is not yet supported in this release.

How Reliable Is the Beta?

The module is a pre-1.0 beta. For instance, RGB issuance forwarding already exists in the runtime JavaScript, but the team hasn’t documented it as a public API yet. For issuing assets, they point developers to the separate on-chain module, @utexo/wdk-wallet-rgb. Atomic-swap capability similarly stays outside the public account surface for now.

The module is also community-maintained: Tether built WDK, but doesn’t take on this specific module’s maintenance or security. The documentation says so explicitly, leaving responsibility for the module’s security and upkeep entirely to Utexo. For anyone evaluating whether to build on it, the matter might naturally raise a fair question: how much engineering discipline stands behind this module?

Pull request #28 against the module’s own repository answers that question directly. It bundles 49 commits covering the initial scaffold, the LSP client (with retry logic and HTTPS enforcement), and a test-coverage push from roughly 14.6% to about 98%, alongside a formal review round with 28 comments from a second engineer. None of it changes who is liable if the module breaks in production, but it does show the kind of engineering discipline behind a module which the community still has to audit independently before shipping it.

How Do You Add It to a WDK App?

Any app already using WDK can add RGB Lightning support by installing the module and adding it to the WDK module configuration. In the app, that configuration lives in the WDK config file, where developers declare which wallet packages the build should compile into the WDK Worklet Bundle.

For a full walkthrough of the build, watch the technical demo Utexo published alongside the announcement.

Further Reading


Similar Posts