Skip to content

Add WASM/wasm-bindgen support to cdk-ffi#1665

Draft
crodas wants to merge 1 commit intocashubtc:mainfrom
crodas:feature/experiment-wasm-ffi
Draft

Add WASM/wasm-bindgen support to cdk-ffi#1665
crodas wants to merge 1 commit intocashubtc:mainfrom
crodas:feature/experiment-wasm-ffi

Conversation

@crodas
Copy link
Collaborator

@crodas crodas commented Feb 21, 2026

Description

This is the evolution of #1660, using the same FFI crate for exporting the wasm data.

Add a WebAssembly target to cdk-ffi alongside the existing UniFFI native bindings. This enables using the CDK wallet directly from browsers via wasm-bindgen.

Key changes:

  • Make UniFFI, SQLite, and tokio multi-thread dependencies optional behind a new uniffi-bindings feature (enabled by default)
  • Add wasm feature with wasm-bindgen, js-sys, web-sys, and related dependencies
  • Implement LocalStorage-backed WalletDatabase for browser persistence
  • Add wasm-bindgen wallet exports wrapping the existing FFI Wallet API
  • Add WASM init function with panic hook and console tracing
  • Gate native-only modules (database, logging, sqlite, wallet_repository) behind uniffi-bindings feature
  • Replace std::time::SystemTime with web_time::SystemTime across all crates to avoid WASM panics
  • Add web-time dependency to cdk-fake-wallet, cdk-ldk-node, and cdk-npubcash
  • Include sample index.html for browser testing
  • Add justfile targets for WASM build

This larger PR will be split into smaller chunks; for instance, lescuer97#17 and #1662 are the first contributions. The following contribution would be to use the native websocket in #1615 with no external deps. The goal is to have this PR smaller, but here is a rough north picture of wasm support.

Here is a wallet in the browser using the wasm build:

image

Notes to the reviewers


Suggested CHANGELOG Updates

CHANGED

ADDED

REMOVED

FIXED


Checklist

Add a WebAssembly target to cdk-ffi alongside the existing UniFFI native
bindings. This enables using the CDK wallet directly from browsers via
wasm-bindgen.

Key changes:

- Make UniFFI, SQLite, and tokio multi-thread dependencies optional behind a
  new `uniffi-bindings` feature (enabled by default)
- Add `wasm` feature with wasm-bindgen, js-sys, web-sys, and related
  dependencies
- Implement LocalStorage-backed WalletDatabase for browser persistence
- Add wasm-bindgen wallet exports wrapping the existing FFI Wallet API
- Add WASM init function with panic hook and console tracing
- Gate native-only modules (database, logging, sqlite, wallet_repository)
  behind `uniffi-bindings` feature
- Replace std::time::SystemTime with web_time::SystemTime across all crates to
  avoid WASM panics
- Add web-time dependency to cdk-fake-wallet, cdk-ldk-node, and cdk-npubcash
- Include sample index.html for browser testing
- Add justfile targets for WASM build
@crodas crodas force-pushed the feature/experiment-wasm-ffi branch from ec7250b to 5b75033 Compare February 21, 2026 14:24
@crodas crodas self-assigned this Feb 21, 2026
Copy link
Collaborator

@thesimplekid thesimplekid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is better then #1660 in that it has less boiler plate. However, it still creates wasm specefic fns and boilerplate. Did you evaluate the use of the uniffi plugin project for js I recommended on that PR (https://github.com/jhugman/uniffi-bindgen-react-native)? Is there a specefic reason we cannot use that so our wasm and kotlin/swift bindings are the same?

I think this is our best model to follow it uses uniffi for all bindings including js, dart and go.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think using local storage is the best option. We should at least be using index db. I've even some some cases of using redb that we already support in the browser. With one of the browser file store apis, though this might be more on the experimental end and have compatibility issues. However, would be nice if it did work as we would avoid having another db backend with migrations etc.

Either way I think best we move the wasm storage to a PR that depends on this one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this example, I would move the storage to pure JavaScript.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move the storage to pure JavaScript.

I do not think we want to do this. We're a rust project we don't want to be maintaining js. Maybe I am misunderstanding what you mean.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant that whatever works in the browser already should be used and optimized later. The main focus is to enable CDKs in the browser. I'll give it a try with redb.

The storage layer should not be a concern at this stage. I would explore implementing the storage in pure JS alongside the test index.html, which is part of our example.

Copy link
Collaborator

@thesimplekid thesimplekid Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fedimint-sdk uses redb with the Origin_private_file_system api. They have also been doing some work with react native using the uniffi plugin I've linked previously https://github.com/MrImmortal09/fedimint-sdk-ffi/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

2 participants