walletkit-web 0.21.3 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,28 +1,116 @@
1
- # `@worldcoin/walletkit-web`
1
+ # `walletkit-web`
2
2
 
3
- Browser WebAssembly bindings for WalletKit.
3
+ WalletKit's browser client. The package always runs Rust/WASM, cryptography,
4
+ proof generation and SQLite in a dedicated Web Worker. Importing the package
5
+ is safe during SSR; call `initializeWalletKit` in a browser.
4
6
 
5
- > PROTOTYPE: this package is private while its generation and publication
6
- > workflow is being validated.
7
+ ```ts
8
+ import { initializeWalletKit } from "walletkit-web";
9
+
10
+ const wallet = await initializeWalletKit({
11
+ databaseKey, // Uint8Array containing the resolved 32-byte K_intermediate
12
+ storageId: "my-account", // stable namespace for this consumer/account
13
+ environment: "staging", // defaults to production
14
+ region: "eu",
15
+ });
16
+ const recovery = await wallet.recoveryDataFromSeed(seed);
17
+ // For an already registered account:
18
+ await wallet.initializeAuthenticator(seed);
19
+ const proofJson = await wallet.generateProof(requestJson);
20
+ await wallet.close();
21
+ ```
22
+
23
+ The host supplies the resolved `databaseKey`, for example after obtaining passkey
24
+ PRF output and deriving the database key. PRF acquisition/derivation happens before
25
+ initialization; WalletKit does not call WebAuthn or wrap this key in an envelope.
26
+ The worker constructs `StorageKeys.fromBytes(databaseKey)` and passes those keys to
27
+ `CredentialStore`. Both vault and cache use that key directly through sqlite3mc.
28
+
29
+ Supply the same key and storage ID when reopening. The authenticator seed and
30
+ database key are separate inputs. The package does not persist the database key;
31
+ initialization copies it and the caller owns clearing its own copy. Rust keeps the
32
+ resolved key in zeroizing memory until its last owner releases it.
33
+
34
+ Mobile hosts can instead resolve `openOrCreateStorageKeys(paths, keystore,
35
+ blobStore, now)` before constructing the same `CredentialStore(paths, keys)`.
36
+ The store retains no keystore or blob-store references. It releases its key
37
+ reference on destruction and requires a new instance to reopen. The host separately
38
+ calls `deleteStorageKeyEnvelope(paths, blobStore)` if it owns an envelope that should
39
+ be deleted. Existing envelope-backed databases still use their resolved intermediate
40
+ key; the old wrapping secret is not a replacement for that database key.
41
+
42
+ ## Browser API
43
+
44
+ All calls into the worker return Promises. The public client exposes
45
+ `recoveryDataFromSeed`, `register`, `pollRegistration`, `initializeAuthenticator`,
46
+ `prepareCredential`, `storeCredential`, and `generateProof`. Registration polling
47
+ returns plain status records, including failure details. `prepareCredential`
48
+ returns the subject and serialized blinding factor for an issuer flow;
49
+ `storeCredential` accepts credential bytes and that factor. Issuer HTTP calls and
50
+ relying-party request construction remain application code.
51
+
52
+ This replaces the prototype API that returned the generated UniFFI namespace.
53
+ Generated Rust objects are internal and never cross the worker boundary. Existing
54
+ consumers must migrate their calls to the browser client; it is not a transparent
55
+ proxy for every generated binding. See the Next.js demo for a complete registration,
56
+ issuance and proof flow.
7
57
 
8
- The package owns the compiled WalletKit module, generated TypeScript bindings,
9
- UniFFI player setup, and WASM asset resolution. Browser applications initialize
10
- it through one interface:
58
+ Operations run in order, including asynchronous work. `close()` drains queued
59
+ operations, destroys owned Rust objects and terminates the worker. `terminate()`
60
+ interrupts immediately and rejects pending requests. Worker failures also reject
61
+ pending requests. An optional `signal` cancels initialization only; after it
62
+ resolves, use `close()` or `terminate()`.
63
+
64
+ ## Assets and deployment
65
+
66
+ Default URLs are resolved by the application's bundler. Both worker JavaScript
67
+ and the roughly 40 MB WASM asset ship in `dist`. The worker is self-contained,
68
+ including the generated glue and its runtime dependencies.
69
+
70
+ Hosts with custom asset layouts can provide explicit URLs:
11
71
 
12
72
  ```ts
13
- const { initializeWalletKit } = await import("@worldcoin/walletkit-web");
14
- const walletKit = await initializeWalletKit();
73
+ const wallet = await initializeWalletKit({
74
+ databaseKey,
75
+ workerUrl: "/assets/walletkit.worker.js",
76
+ wasmUrl: "/assets/walletkit.wasm",
77
+ });
15
78
  ```
16
79
 
17
- Build it from the repository root with the pinned toolchain:
80
+ Relative overrides resolve against the page URL. These options change asset
81
+ locations; they do not enable main-thread execution. Serve the worker from a
82
+ permitted same-origin location and the WASM file as `application/wasm`.
83
+
84
+ ## Persistent storage
85
+
86
+ Initialization acquires the OPFS sync-access-handle pool asynchronously. SQLite
87
+ operations are synchronous afterward. The browser's direct-key path needs no envelope database. The encrypted credential
88
+ vault/cache retain their existing format and use rollback journals on WASM.
89
+
90
+ Closing a SQLite connection does not release the pool's OPFS handles: the pool
91
+ remains alive until worker termination. Currently one worker owns the WalletKit
92
+ pool per origin. A second tab/client receives an initialization error, even with
93
+ a different storage ID. After shutdown, browser handle release may be asynchronous;
94
+ a subsequent initializer may need to retry. There is no silent memory fallback.
95
+ Pool capacity is reserved at startup rather than expanded during synchronous SQL.
96
+
97
+ Browser storage requires a supported secure context (localhost is suitable for
98
+ development). The SAH pool does not require cross-origin-isolation headers.
99
+ Browser quota and eviction policy still apply.
100
+
101
+ ## Build and verify
18
102
 
19
103
  ```sh
20
- nix develop .#wasm --command npm --prefix web/walletkit install
21
- nix develop .#wasm --command npm --prefix web/walletkit run build
104
+ nix develop .#wasm --command bun install --cwd web/walletkit --frozen-lockfile
105
+ nix develop .#wasm --command bun run --cwd web/walletkit build
106
+ nix develop .#wasm --command bun run --cwd web/walletkit test:browser
22
107
  ```
23
108
 
24
- The release build uses `crates/walletkit` directly, disables its default
25
- features except for `embed-zkeys`, and optimizes the generated module with
26
- `wasm-opt -Oz --converge`. Embedding the proving artifacts currently makes the
27
- optimized WASM roughly 40 MB; lazy artifact delivery and worker placement are
28
- still future production work.
109
+ Browser tests use installed Google Chrome and a production Vite fixture. They
110
+ cover worker startup and lifecycle, URL overrides, exclusive pool ownership,
111
+ wrong-key rejection, and reopening storage with directly supplied keys.
112
+ `bun run bundle` reuses generated bindings for TypeScript-only development.
113
+
114
+ The example uses a new namespace and memory-only database keys on each load. Its encrypted
115
+ files persist, but it intentionally cannot unlock them after reload; a production
116
+ host must implement key recovery/unlock and stable account namespace selection.
Binary file
@@ -12,22 +12,32 @@ export function __wbg_addEventListener_520e749bbae24529(...args: any[]): any;
12
12
  export function __wbg_addEventListener_d85450ee1320c989(...args: any[]): any;
13
13
  export function __wbg_append_01c74e5c6b58aa64(...args: any[]): any;
14
14
  export function __wbg_arrayBuffer_3b637f0fa65c5351(...args: any[]): any;
15
+ export function __wbg_buffer_54b87055582c8a81(arg0: any): any;
16
+ export function __wbg_byteLength_41862ca4020b9c43(arg0: any): any;
17
+ export function __wbg_byteOffset_d42e18c4441f628b(arg0: any): any;
15
18
  export function __wbg_call_8a2dd23819f8a60a(...args: any[]): any;
16
19
  export function __wbg_call_a6e5c5dce5018821(...args: any[]): any;
17
20
  export function __wbg_clearTimeout_333bba87532ab9d3(arg0: any): void;
18
21
  export function __wbg_clearTimeout_6b8d9a38b9263d65(arg0: any): void;
19
22
  export function __wbg_close_c65ca0257e895318(...args: any[]): any;
20
23
  export function __wbg_code_1fc52b4142a112ac(arg0: any): any;
24
+ export function __wbg_createSyncAccessHandle_0caafebe31e4f2d9(arg0: any): any;
21
25
  export function __wbg_crypto_38df2bab126b63dc(arg0: any): any;
22
26
  export function __wbg_data_328de4280640da92(arg0: any): any;
23
27
  export function __wbg_dispatchEvent_ca78eaf3d469bc25(...args: any[]): any;
24
28
  export function __wbg_done_89b2b13e91a60321(arg0: any): any;
29
+ export function __wbg_entries_3d99c52a47728e2f(arg0: any): any;
25
30
  export function __wbg_entries_900cefd6f70eb290(arg0: any): any;
26
31
  export function __wbg_fetch_074561c3e313c86f(arg0: any): Promise<Response>;
27
32
  export function __wbg_fetch_9dad4fe911207b37(arg0: any): Promise<Response>;
28
33
  export function __wbg_fetch_b5951fc96f52f786(arg0: any, arg1: any): any;
34
+ export function __wbg_fill_5663f5c647107cce(arg0: any, arg1: any, arg2: any, arg3: any): any;
35
+ export function __wbg_flush_a4bd8d4e05ad23f6(...args: any[]): any;
29
36
  export function __wbg_getDate_a1a40c1c5f40fe3b(arg0: any): any;
30
37
  export function __wbg_getDay_aa318cce5da74c49(arg0: any): any;
38
+ export function __wbg_getDirectoryHandle_cf175faf1a75a384(arg0: any, arg1: any, arg2: any, arg3: any): any;
39
+ export function __wbg_getDirectory_389283588dfb8117(arg0: any): any;
40
+ export function __wbg_getFileHandle_72de55ab3ca9ad57(arg0: any, arg1: any, arg2: any, arg3: any): any;
31
41
  export function __wbg_getFullYear_6af8b229792ae254(arg0: any): any;
32
42
  export function __wbg_getHours_9f6561095682ce51(arg0: any): any;
33
43
  export function __wbg_getMinutes_b0d5cd90bf9b8f22(arg0: any): any;
@@ -37,22 +47,29 @@ export function __wbg_getRandomValues_3f44b700395062e5(...args: any[]): any;
37
47
  export function __wbg_getRandomValues_bf16787eede473f5(...args: any[]): any;
38
48
  export function __wbg_getRandomValues_c44a50d8cfdaebeb(...args: any[]): any;
39
49
  export function __wbg_getSeconds_40c565b3a6cb05fe(arg0: any): any;
50
+ export function __wbg_getSize_29187e13478442fb(...args: any[]): any;
40
51
  export function __wbg_getTime_d6f070c088c9b5ed(arg0: any): any;
41
52
  export function __wbg_getTimezoneOffset_dc9862c79e5a81a3(arg0: any): any;
53
+ export function __wbg_getUint32_11fb2913bdb7d394(arg0: any, arg1: any): any;
42
54
  export function __wbg_get_507a50627bffa49b(arg0: any, arg1: any): any;
55
+ export function __wbg_get_78f252d074a84d0b(...args: any[]): any;
43
56
  export function __wbg_get_c7eb1f358a7654df(...args: any[]): any;
57
+ export function __wbg_get_index_e68b01fac18aa799(arg0: any, arg1: any): any;
44
58
  export function __wbg_has_8374cf06984d8bfc(...args: any[]): any;
45
59
  export function __wbg_headers_cf9c80f30e2a4eff(arg0: any): any;
46
60
  export function __wbg_instanceof_ArrayBuffer_4480b9e0068a8adb(arg0: any): boolean;
47
61
  export function __wbg_instanceof_Error_1fdac9f13a8181ba(arg0: any): boolean;
48
62
  export function __wbg_instanceof_Response_c8b64b2256f01bec(arg0: any): boolean;
63
+ export function __wbg_instanceof_WorkerGlobalScope_8ec07b5e040a41c3(arg0: any): boolean;
49
64
  export function __wbg_isArray_0677c962b281d01a(arg0: any): arg0 is any[];
50
65
  export function __wbg_iterator_6f722e4a93058b71(): symbol;
51
66
  export function __wbg_length_1f0964f4a5e2c6d8(arg0: any): any;
52
67
  export function __wbg_message_8326fb1d549bebc5(arg0: any): any;
53
68
  export function __wbg_msCrypto_bd5a034af96bcba6(arg0: any): any;
54
69
  export function __wbg_name_b0b4809690944614(arg0: any): any;
70
+ export function __wbg_navigator_51379c10a84aeec9(arg0: any): any;
55
71
  export function __wbg_new_0_3da9e97f24fc69be(): Date;
72
+ export function __wbg_new_0c72e559145ea733(arg0: any, arg1: any, arg2: any): DataView<any>;
56
73
  export function __wbg_new_0d809930cd1354c6(...args: any[]): any;
57
74
  export function __wbg_new_4339b2a2675a03e3(...args: any[]): any;
58
75
  export function __wbg_new_bf8729ffe10e9ee7(...args: any[]): any;
@@ -66,11 +83,14 @@ export function __wbg_new_with_str_and_init_d95cbe11ce28e65e(...args: any[]): an
66
83
  export function __wbg_new_with_year_month_day_f2354b74b4b2a4f3(arg0: any, arg1: any, arg2: any): Date;
67
84
  export function __wbg_next_6dbf2c0ac8cde20f(arg0: any): any;
68
85
  export function __wbg_next_71f2aa1cb3d1e37e(...args: any[]): any;
86
+ export function __wbg_next_dfa6c7f0ee891663(...args: any[]): any;
69
87
  export function __wbg_node_84ea875411254db1(arg0: any): any;
70
88
  export function __wbg_process_44c7a14e11e9f69e(arg0: any): any;
71
89
  export function __wbg_prototypesetcall_4770620bbe4688a0(arg0: any, arg1: any, arg2: any): void;
72
90
  export function __wbg_randomFillSync_6c25eac9869eb53c(...args: any[]): any;
73
91
  export function __wbg_random_039a7d5d06e0d333(): number;
92
+ export function __wbg_read_27d98fb08886b1fc(...args: any[]): any;
93
+ export function __wbg_read_ab82a1efee669e3b(...args: any[]): any;
74
94
  export function __wbg_readyState_50bc38c2a9e83db6(arg0: any): any;
75
95
  export function __wbg_reason_5dc8e429d537d6a9(arg0: any, arg1: any): void;
76
96
  export function __wbg_removeEventListener_a3f23c70077bdcc1(...args: any[]): any;
@@ -79,10 +99,15 @@ export function __wbg_send_a321b376d40ec867(...args: any[]): any;
79
99
  export function __wbg_send_df98dd5ede9b3f4d(...args: any[]): any;
80
100
  export function __wbg_setTimeout_3a808dd861dd3c12(arg0: any, arg1: any): number;
81
101
  export function __wbg_setTimeout_f757f00851f76c42(arg0: any, arg1: any): number;
102
+ export function __wbg_setUint32_1a26b3818324ed47(arg0: any, arg1: any, arg2: any): void;
103
+ export function __wbg_set_4d7dd76f3dae2926(arg0: any, arg1: any, arg2: any): void;
104
+ export function __wbg_set_at_674f6538cd77adef(arg0: any, arg1: any): void;
82
105
  export function __wbg_set_binaryType_a37b086c78ca7c29(arg0: any, arg1: any): void;
83
106
  export function __wbg_set_body_029f2d171e0a005f(arg0: any, arg1: any): void;
84
107
  export function __wbg_set_cache_b4a740b195c051f4(arg0: any, arg1: any): void;
85
108
  export function __wbg_set_code_9d09aecd77d789f4(arg0: any, arg1: any): void;
109
+ export function __wbg_set_create_a807a6e9ac628698(arg0: any, arg1: any): void;
110
+ export function __wbg_set_create_fa1dfa475fac91e9(arg0: any, arg1: any): void;
86
111
  export function __wbg_set_credentials_bb34a40189e3b43b(arg0: any, arg1: any): void;
87
112
  export function __wbg_set_headers_9c61d123c3ee1f10(arg0: any, arg1: any): void;
88
113
  export function __wbg_set_method_5532d59b92d76467(arg0: any, arg1: any, arg2: any): void;
@@ -96,15 +121,20 @@ export function __wbg_static_accessor_GLOBAL_THIS_8d1badc68b5a74f4(): any;
96
121
  export function __wbg_static_accessor_SELF_146583524fe1469b(): any;
97
122
  export function __wbg_static_accessor_WINDOW_f2829a2234d7819e(): any;
98
123
  export function __wbg_status_c45b3b9b3033184a(arg0: any): any;
124
+ export function __wbg_storage_3c893ad40b9e831e(arg0: any): any;
99
125
  export function __wbg_stringify_b54333f60f1e4dad(...args: any[]): any;
100
126
  export function __wbg_subarray_3ed232c8a6baee09(arg0: any, arg1: any, arg2: any): any;
101
127
  export function __wbg_text_d3a29f7525a132c3(...args: any[]): any;
102
128
  export function __wbg_then_16d107c451e9905d(arg0: any, arg1: any, arg2: any): any;
103
129
  export function __wbg_toString_bac9199ff382784d(arg0: any): any;
130
+ export function __wbg_truncate_8832884f3fa99eab(...args: any[]): any;
131
+ export function __wbg_truncate_98a6032d23095328(...args: any[]): any;
104
132
  export function __wbg_url_abdb8fb08377f8c0(arg0: any, arg1: any): void;
105
133
  export function __wbg_value_a5d5488a9589444a(arg0: any): any;
106
134
  export function __wbg_versions_276b2795b1c6a219(arg0: any): any;
107
135
  export function __wbg_wasClean_3c7aa2335da09e74(arg0: any): any;
136
+ export function __wbg_write_66c6f8f1293992eb(...args: any[]): any;
137
+ export function __wbg_write_e557b5312ec23477(...args: any[]): any;
108
138
  export function __wbindgen_cast_0000000000000001(arg0: any, arg1: any): {
109
139
  (...args: any[]): any;
110
140
  _wbg_cb_unref(): void;