Develop the browser package
This page describes how to build and test @worldcoin/walletkit-web and how to
expose a walletkit-core API to the browser. For the design behind these steps,
see How the browser package works.
Before you begin
- Install Nix. The
wasmdevshell pins the Rust toolchain, thewasm-bindgenCLI, Binaryen, and Bun. Without Nix, you can run the devshell in Docker withnix/docker.sh; for details, see Nix development environments. - To run the browser tests, install Google Chrome on the machine that runs them.
Playwright drives the installed Chrome (the
chromechannel), not its bundled Chromium, and neither the devshell nor the Docker wrapper provides Chrome.
Run every command on this page from the repository root.
Build the package
-
Install the JavaScript dependencies:
nix develop .#wasm --command bun install --cwd web/walletkit --frozen-lockfile -
Build the WASM module and the TypeScript bundle into
web/walletkit/dist:nix develop .#wasm --command bun run --cwd web/walletkit build
To rebuild after a TypeScript-only change, run the following command. It reuses the WASM module from the last full build:
nix develop .#wasm --command bun run --cwd web/walletkit bundle
Test the package
To run the browser tests, run the following command. It type-checks the tests and the fixture app, builds the fixture with Vite, and runs the Playwright tests in Chrome:
nix develop .#wasm --command bun run --cwd web/walletkit test:browser
The tests are in web/walletkit/tests:
browser.spec.tsdrives the built package in a page.types/consumer.tschecks the public TypeScript API at compile time. To check that an invalid call doesn’t compile, mark it with// @ts-expect-error.
CI also lints the crate and checks the TypeScript formatting. To run the same checks, run these commands:
nix develop .#wasm --command cargo clippy -p walletkit-web --no-deps \
--target wasm32-unknown-unknown --locked -- -D warnings
nix develop .#wasm --command bun run --cwd web/walletkit format:check
The Next.js example is the package’s integration consumer. CI type-checks, tests, and builds it against the package from the same checkout.
Expose a core API to the browser
The worker and the page proxy dispatch new exports without changes, but the
public type names are listed by hand. To expose a walletkit-core class or
function, do the following:
- In
crates/walletkit-web/src, add a wrapper with#[wasm_bindgen]. Follow the conventions of the wrappers there:- Keep the UniFFI name and arguments, with
js_nameincamelCase. - Hold the core object in an
Arc, so that asynchronous methods can return a'staticfuture. - Take a
u64as aBigIntand validate it withjs::u64_arg. - Return records as plain objects built with
js::object. - Return a
Promisefrom asynchronous methods withjs::promise. - Convert errors with
error::to_js, and reject invalid arguments witherror::invalid_argument, which throws aTypeError.
- Keep the UniFFI name and arguments, with
- For a class, add a
RemoteObjecttype alias inremote.tsand export it fromindex.ts. For a record or an enum, export its generated type fromindex.ts. - Add compile-time checks to
tests/types/consumer.tsand a browser test totests/browser.spec.ts. - If the API appears in
Browser limitations, remove it from that
table in
web/walletkit/README.md.